//============================================================================================
/**
 * @file	poke_select.c
 * @brief	ポケモン選択
 * @author	Nozomu Saito
 */
//============================================================================================
//
#include "application/poke_select.h"

#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/snd_tool.h"
#include "system/touch_subwindow.h"
#include "system/wipe.h"
#include "system/clact_tool.h"

#include "gflib/touchpanel.h"

#include "poketool/boxdata.h"
#include "poketool/pokeparty.h"
#include "poketool/monsno.h"
#include "poketool/pokeicon.h"
#include "poketool/poke_tool.h"
#include "../../poketool/poke_tool_def.h"		/* ##### */
#include "savedata/savedata.h"

#include "poke_sel.naix"

#include "system/wordset.h"
#include "system/msgdata_util.h"
#include "system/fontproc.h"
#include "system/pmfprint.h"


#include "system/window.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_poke_select.h"

#include "key_link_control.h"

//セルアクター最大数
#define CELL_ACTOR_MAX			( 30+3+3+3+2+1+1 )
//↑ポケモン30+マーカー3+ボタン3+ドロップポケモン3+ドロップ禁止パネル2+ 半透明ポケモン1+煙1

#define SELECT_POKEMON_FULL		(0)		// すでにいっぱい
#define SELECT_POKEMON_SELECT	(1)		// 選択した
#define SELECT_POKEMON_CANCEL	(2)		// 解除した
#define SELECT_POKEMON_NOMONS	(3)		// そもそもそこにいない
#define SELECT_POKEMON_EGG		(4)		// 実はたまごだった

#define SELECT_POKE_APP_MAX			(3)		//アプリが許すポケモン選択最大数
#define BOX_APP_MAX					(MYPARTY_BOX)	//アプリが許す最大ボックスナンバー

#define MYPARTY_BOX_SEL_MAX	(6)

#define POKEMON_ICON_MAX			(30)		//ポケモンアイコン
#define SCREEN_TOUCH_MAX			(3)			//右ボタン・左ボタン・やめるボタン

#define TOUCH_RECT_COMMON_MAX		(POKEMON_ICON_MAX+SCREEN_TOUCH_MAX+1) //どのアプリから呼ばれても、最低限確保する矩形数
#define ICON_CANCEL			(POKEMON_ICON_MAX+0)
#define ICON_ARROWL			(POKEMON_ICON_MAX+1)
#define ICON_ARROWR			(POKEMON_ICON_MAX+2)
#define ICON_DROP_POKEMON	(POKEMON_ICON_MAX+SCREEN_TOUCH_MAX)	//選択済みポケモンアイコン開始インデックス
#define ICON_TERMINATE		(POKEMON_ICON_MAX+SCREEN_TOUCH_MAX+ptr->SelectPokeMax)

// ポケモンの表示設定
#define POKEMON_WIDTH			(/*40*/24)
#define POKEMON_HEIGHT			(24)
#define POKEMON_BASEX			(/*28*/20)
#define POKEMON_BASEY			(40)

// ポケモンアイコンが始まるVRAM上でのオフセット
#define POKEICON_VRAM_OFFSET	( 0x40 )
#define DROP_POKEICON_VRAM_OFFSET	( 0x222 )
#define GHOST_POKEICON_VRAM_OFFSET	( 0x2b1 )

#define POKEICON_TRANS_CHARA	(4*4)
#define POKEICON_TRANS_SIZE		(POKEICON_TRANS_CHARA*0x20)

//ポケモンアイコンのアニメインデックスオフセット
#define POKE_ICON_ANM_OFS		(7)
//右ボタンのアニメインデックスオフセット
#define R_ARROW_ICON_ANM_OFS		(2)
//左ボタンのアニメインデックスオフセット
#define L_ARROW_ICON_ANM_OFS		(0)
//やめるボタンのアニメインデックスオフセット
#define CANCEL_ICON__ANM_OFS		(4)
//決定アイコンのアニメインデックスオフセット
#define DECIDE_ICON_ANM_OFS		(6)
//ドロップポケモンアイコンのアニメインデックスオフセット
#define DROP_POKE_ICON_ANM_OFS	(39)
//カーソルのアニメインデックスオフセット
#define CURSSOR_ICON_ANM_OFS		(45)
//つかむカーソルのアニメインデックスオフセット
#define CURSSOR_GRASP_ICON_ANM_OFS		(46)
//ドロップ禁止パネルのアニメインデックスオフセット
#define PANEL_ICON_ANM_OFS		(47)
//常時半透明ポケモンのアニメインデックスオフセット
#define GHOST_ICON_ANM_OFS		(48)
//煙アニメインデックスオフセット
#define SMOG_ANM_OFS		(50)

// ポケモンアイコンのパレットを転送するオフセット
#define POKEICON_PAL_OFFSET		(  8 )


#define POKEMON_NOSELECT	(-1)	//ポケモン選択されてない

#define MSG_FLAG_CENTER		(0x01)

#define	FONT_PALNO_NORMAL	(13)	/* ノーマルパレット */
#define	FONT_PALNO_TOUCH	(12)	/* タッチパレット */
#define	TITLE_FONT_COLOR		(GF_PRINTCOLOR_MAKE( 1, 2, 0))
#define	MSG_FONT_COLOR		(GF_PRINTCOLOR_MAKE( 1, 2, 15))
#define	MSG_TFONT_COLOR		(GF_PRINTCOLOR_MAKE( 15, 1, 0))

//ドロップポイント関連
#define DROP_ICON_X_BASE	(26*8+4)
#define DROP_ICON_Y_BASE	(5*8+4)
#define DROP_ICON_Y_OFS	(5*8)
#define DROP_ICON_DRAW_OFS	(-4)

#define	GRASP_OFS	(4*FX32_ONE)

//ドロップポイント矩形
#define DROP_POINT_X_BASE	(24*8)
#define DROP_POINT_Y_BASE	(4*8)
#define DROP_POINT_WIDTH	(32)
#define DROP_POINT_HEIGHT	(24)

//ボックスタイトル
#define BOX_TITLE_SX		(4)
#define BOX_TITLE_SY		(1)
#define BOX_TITLE_WIDTH		(13)
#define BOX_TITLE_HEIGHT	(2)
#define BOX_TITLE_CGX_SIZE	(BOX_TITLE_WIDTH*BOX_TITLE_HEIGHT)

//「やめる」
#define EXIT_SX		(26)
#define EXIT_SY		(21)
#define EXIT_WIDTH		(6)
#define EXIT_HEIGHT	(2)
#define EXIT_CGX_SIZE	(EXIT_WIDTH*EXIT_HEIGHT)

#define BOX_TITLEBASE		(0xA0)		//160キャラ
#define EXIT_BASE			(BOX_TITLEBASE+BOX_TITLE_CGX_SIZE)
#define MSG_BASE			(EXIT_BASE+EXIT_CGX_SIZE)	//他のWINと違いBG3を使うが、キャラベースを同じにしてあるので、オフセットは続きで定義

#define	BOX_TITLE_STR_BUFF	(64)

//返却トレー矩形
#define DROP_TRAY_X		(1*8)
#define DROP_TRAY_Y		(4*8)
#define DROP_TRAY_W		(18*8)
#define DROP_TRAY_H		(15*8)

//ボタン類の位置
#define BTN_POS_X_TERMINATE	(28*8)
#define BTN_POS_Y_TERMINATE	(176)
#define BTN_POS_X_ARROWR	(18*8)
#define BTN_POS_Y_ARROWR	(2*8)
#define BTN_POS_X_ARROWL	(16)
#define BTN_POS_Y_ARROWL	(16)

//ボックス名ウィンドウのカーソル位置
#define BOX_NAME_POS_X	(10*8)
#define BOX_NAME_POS_Y	(16)


#define TRAY_POS_X		(228)
#define TRAY_POS_Y		(176)

//タッチフォントパレット
#define TFONT_FRAMECOL		(FONT_PALNO_TOUCH)
//メッセージウィンドウ
#define SFONT_FRAMECOL		(FONT_PALNO_NORMAL)
#define POKEMON_TFRAMECHR	(0x3F0 - TALK_WIN_CGX_SIZ)
#define POKEMON_TFRAMECOL	(11)


//OBJ表示プライオリティー
#define PRI_DEFAULT	(20)
#define PRI_BUTTON	(10)
#define PRI_CURSSOR	(1)
#define PRI_GHOST_POKE	(8)
#define PRI_POKE_ICON	(6)
#define PRI_MARK	(4)
#define PRI_DRAG_POKE_ICON	(3)

//ボックスフィル領域(キャラ)
#define FILL_BOX_W	(20)
#define FILL_BOX_H	(20)
//YESNO描画位置
#define YESNO_X	(25)
#define YESNO_Y	(15)

#define MSG_WIN_X	(2)
#define MSG_WIN_Y	(21)
#define MSG_WIN_W	(21)
#define MSG_WIN_H	(2)

#define BRIGHT_VAL	(-7)

#define TITLE_WRITE_OFS	(4)

#define SUB_DISTANCE	(256*FX32_ONE)

#define BLEND_EVA	(0x06)
#define BLEND_EVB	(0x0a)


typedef enum {
	ICON_TYPE_NONE,
	BOX_POKE_ICON,
	DROP_POKE_ICON,
}POKE_ICON_TYPE;

typedef enum {
	MAIN_SEQ_POKE_SELECT,
	MAIN_SEQ_SEL_CHECK_READY,
	MAIN_SEQ_SELECT_CHECK,
	MAIN_SEQ_SELECT_COPY,
	MAIN_SEQ_ENTRY_POKE_CANCEL,
	MAIN_SEQ_ENTRY_POKE_CANCEL_CHECK,
	MAIN_SEQ_SELECT_END,
}MAIN_SEQ;

typedef enum {
	DROP_NG,
	DROP_BOX_TO_AREA,
	DROP_RETURN,
	DROP_AREA_TO_AREA,
}DROP_TYPE;

typedef struct {
  CLACT_WORK_PTR Clact;
  BOX_POKE_DATA	PokeData;
} POKEMON_ICON;

typedef struct {
  CLACT_WORK_PTR Icon;
  int PokeNo;
  int BoxNo;
} MARK_ICON;

typedef struct {
  int Adrs;				// VRAMアドレス
  int PalNo;				// パレット番号
  CLACT_WORK_PTR Icon;			// CLACT
  u8 CharBuf[POKEICON_TRANS_SIZE];	// キャラクタバッファ
} POKEBUF;

typedef struct {
	void	*BoxData;		//ボックスデータ
	POKEPARTY	*MyParty;		//手持ちポケモン
}POKE_ACCESS_WORK;

typedef struct GET_DATA_FUNC_TBL_tag{
	GET_BOX_POKE_DATA	GetBoxPokeData;
	GET_BOX_NAME		GetBoxName;
}GET_DATA_FUNC_TBL;

typedef struct {
	u32 x;
	u32 y;
}POINT;

typedef struct {
	BOOL	State;
	int		TargetIdx;
	VecFx32 OrgVec;
	POINT   Point;
	POKE_ICON_TYPE	IconType;
	POKEMON_ICON	*IconTbl;
}POKE_DRAG;

typedef struct {
	u8 Top;
	u8 Left;
	u8 Bottom;
	u8 Right;
	BOOL Drop;
}DROP_POINT;

typedef struct {
	int BoxIndex;		//0〜BoxNumMax-1
	int PokeIndex;		//0〜29
	int MarkIndex;		//0〜SelectPokeMax-1
	BOOL Valid;
}DROP_ICON_DATA;			//暫定構造体。機能過多かも


//カーソル制御
typedef struct CUR_AREA_tag
{
	u8 X;
	u8 Y;
	u8 W;
	u8 H;
	u16 IdxMax;
	u16 Idx;
}CUR_AREA;

//カーソル制御
typedef struct CURSSOR_CONT_tag
{
	CLACT_WORK_PTR Curssor;
	CUR_AREA CurArea[4];
}CURSSOR_CONT;

typedef struct POKE_SELECT_WORK_tag
{
	GF_BGL_INI *bgl;
	int HeapID;

	// 下画面ウインドウシステム
	TOUCH_SW_SYS *TouchSubWindowSys;

//外部決定パラメータ
	u8 CancelFlg;	//アプリを途中キャンセルできるかのフラグ
	u8 SelectPokeMax;	//選択できるポケモンの最大数(0は禁止とする)
	u8 Selected;
	u8 CurrentBox;		//現在のボックス番号

	u8 BoxNumMax;		//ボックス最大数
	u8 ItemVisible;		//アイテム表示するか			//未使用
	u8 BallVisible;		//カスタムボール表示するか		//未使用
	u8 CancelOK;		//キャンセル可・不可

	int Seq;

	// セルアクター関連
	CLACT_SET_PTR	ClactSet;				// セルアクターセット
	CLACT_U_EASYRENDER_DATA RendData;			// 簡易レンダーデータ
	CLACT_U_RES_MANAGER_PTR ResMan[CLACT_U_RES_MAX];	// リソースマネージャ
	CLACT_U_RES_OBJ_PTR ResObjTbl[CLACT_U_RES_MAX];	// リソースオブジェテーブル
	CLACT_HEADER ClActHeader;
	// ポケモンアイコン 30体分
	POKEMON_ICON	Icon[POKEMON_ICON_MAX];
	//常時半透明ポケモン
	POKEMON_ICON	Ghost;
	RECT_HIT_TBL	*TouchRect;

	POKEMON_ICON	DropIcon[SELECT_POKE_APP_MAX];
	DROP_ICON_DATA	DropIconData[SELECT_POKE_APP_MAX];

	// とじる
	CLACT_WORK_PTR Cancel;
	// 右→
	CLACT_WORK_PTR ArrowR;
	// 左←
	CLACT_WORK_PTR ArrowL;
	//カーソル
	CLACT_WORK_PTR Curssor;
	//煙
	CLACT_WORK_PTR Smog;

	//ドロップ禁止パネル(パネル必要最大数を確保)
	CLACT_WORK_PTR Panel[SELECT_POKE_APP_MAX-1];

	// 決定マーク
	MARK_ICON *Mark;	// n体分(選択できるポケモンの数)

// ポケモンアイコンの高速表示用
	POKEBUF PokeBuf[POKEMON_ICON_MAX];

	POKE_ACCESS_WORK	AccessWork;	//ポケモンデータアクセスワーク

	void (*DrawFunc)(POKEBUF *);
	GET_DATA_FUNC_TBL		GetDataFuncTbl;
//	GET_BOX_POKE_DATA		GetBoxPokeData;

	//タッチ状態制御関連

	// メッセージウィンドウ関連
	GF_BGL_BMPWIN	TitleWin;
	GF_BGL_BMPWIN	MsgWin;
	GF_BGL_BMPWIN	ExitWin;

	//カーソル位置

	//カレント
	POKE_DRAG	PokeDrag;

	//ドロップポイント
	DROP_POINT	*DropPoint;

	//返却トレー =　ボックス矩形
	DROP_POINT	TrayPoint;

	//最後にドロップした位置
	int LastDropIndex;

	SELECT_RESULT_INFO *Result;

	//キーリンクコントローラ
	KEY_LINK_CONT_PTR KeyLinkContPtr;
	BOOL KeyDrag;
	BOOL TouchDrag;
	BOOL TouchTrgFlg;

	void *TemochiBgArc;
	void *BoxBgArc;
	NNSG2dScreenData *TemochiScrnData;
	NNSG2dScreenData *BoxScrnData;

	POKE_SEL_CALL_BACK CallBackFunc;
	void *CallBackWk;
	int TmpBoxPos;
	int TmpBoxNo;

}POKE_SELECT_WORK;

static SELECT_MAIN_RC PokemonSelectMain(POKE_SELECT_WORK_PTR ptr);
static void SelectCheckReady(POKE_SELECT_WORK_PTR ptr);
static void PokemonSelectCheck(POKE_SELECT_WORK_PTR ptr);

static void CancelEntryPokeReady(POKE_SELECT_WORK_PTR ptr);
static void CancelEntryPokeCheck(POKE_SELECT_WORK_PTR ptr);

static void InitCellActor(POKE_SELECT_WORK_PTR ptr);
static void MakeCellActorHeader(POKE_SELECT_WORK_PTR ptr);
static void SetMiscIcon(POKE_SELECT_WORK_PTR ptr);
static void MakeCLACT_ADD(CLACT_ADD *add, POKE_SELECT_WORK_PTR ptr, int param);
static CLACT_WORK_PTR SetOamIcon(POKE_SELECT_WORK_PTR ptr, int x, int y, int anim, int flag);

static void CreateDropPoint(POKE_SELECT_WORK_PTR ptr);
static void SetScreen(POKE_SELECT_WORK_PTR ptr, GF_BGL_INI * ini, const int inHeapID);
static void SetRectHitTable(RECT_HIT_TBL *rect, int x, int y, int sizx, int sizy);
static void SetPokemonIcon(POKE_SELECT_WORK_PTR ptr);
static void RedrawBox(POKE_SELECT_WORK_PTR ptr);
static void RedrawPokemonBox(POKE_SELECT_WORK_PTR ptr);
static void RedrawPokemonMyParty(POKE_SELECT_WORK_PTR ptr);
static void RedrawDropPoint(POKE_SELECT_WORK_PTR ptr, const u8 inIndex, const u8 inPokeIdx, const BOOL move);
static void TransPokeIconFinish(POKEBUF *pbuf);
static int SelectPokemon(POKE_SELECT_WORK_PTR ptr, int inIndex);
static int CheckSelPoke(POKE_SELECT_WORK_PTR ptr, int inIndex);
static int SelectDropPokemon(POKE_SELECT_WORK_PTR ptr, int inIndex);
static int CheckSelDropPoke(POKE_SELECT_WORK_PTR ptr, int inIndex);
static void SetDragPokemon(POKE_SELECT_WORK_PTR ptr, const POKE_ICON_TYPE inIconType, int inIndex);
static void DragPokemon(POKE_SELECT_WORK_PTR ptr);
static void DropPokemon(POKE_SELECT_WORK_PTR ptr);
static DROP_TYPE CheckDropPoint(POKE_SELECT_WORK_PTR ptr);
static void Drop(POKE_SELECT_WORK_PTR ptr, const u8 inIdx);
static void Move(POKE_SELECT_WORK_PTR ptr, const u8 inOrgIdx, const u8 inDstIdx);
static void TransPokeIconCharaPal(BOX_POKE_DATA *inData, POKEBUF *pokeBuf, int no,
		CLACT_WORK_PTR icon, void *buf, ARCHANDLE* handle, const u32 inOfs);
static void GetCharData(u32 dataIdx, NNSG2dCharacterData** charData, void *arcData, ARCHANDLE* handle);
static void DrawBoxTitle(POKE_SELECT_WORK_PTR ptr, int inBoxNumber);
static void DrawExit(POKE_SELECT_WORK_PTR ptr);
static void SetUpBG(GF_BGL_INI * ini, const int inHeapID);
static void BgInit(GF_BGL_INI * ini);

static void CheckSelectPokemonIcon(POKE_SELECT_WORK_PTR ptr);
static void GetMyPartyPokeData(POKE_SELECT_WORK_PTR ptr, const int inIndex, BOX_POKE_DATA *outData );
static void ReturnPokeIcon(POKE_SELECT_WORK_PTR ptr, const int inTargetIdx);
static void SetupMsgWindow(POKE_SELECT_WORK_PTR ptr, const int inMsgID, const int inFont);
static void DeleteWindow(GF_BGL_BMPWIN *win, const BOOL inFrmVanish);

static void DispSelectMsg(POKE_SELECT_WORK_PTR ptr);
static void DelSelectMsgWin(POKE_SELECT_WORK_PTR ptr);

static void CopyResult(POKE_SELECT_WORK_PTR ptr);
static void DeleteCellActor(POKE_SELECT_WORK_PTR ptr);

static void MoveCursor(POKE_SELECT_WORK_PTR ptr);

//キー操作用
static SELECT_MAIN_RC ButtonPushFunc( POKE_SELECT_WORK_PTR ptr );
static SELECT_MAIN_RC ButtonCancelFunc( POKE_SELECT_WORK_PTR ptr );

//キーとタッチで共有する処理とか
static void PushArrowL(POKE_SELECT_WORK_PTR ptr);
static void PushArrowR(POKE_SELECT_WORK_PTR ptr);
static void PushExit(POKE_SELECT_WORK_PTR ptr);

static void DropResultFunc(POKE_SELECT_WORK_PTR ptr, const DROP_TYPE inRC);

static void CallBack(POKE_SELECT_WORK_PTR ptr);

static void SetPassive(void);
static void ClearPassive(void);

//--------------------------------------------------------------------------------------------
/**
 * メモリ確保
 *
 * @param	inHeapID				ヒープID
 * @param	inSelectPokeMax			選択できるポケモン最大数
 * @param	inBoxNumMax				ボックス数
 *
 * @return	POKE_SELECT_WORK_PTR			ワークポインタ
 */
//--------------------------------------------------------------------------------------------
POKE_SELECT_WORK_PTR POKESEL_Alloc(const int inHeapID, const u8 inSelectPokeMax, const u8 inBoxNumMax )
{
	POKE_SELECT_WORK_PTR ptr;
	ptr = sys_AllocMemory(inHeapID, sizeof(POKE_SELECT_WORK));
	//ワークはゼロクリア
	memset(ptr, 0, sizeof(POKE_SELECT_WORK));

	GF_ASSERT(inSelectPokeMax > 0);

	ptr->HeapID = inHeapID;
	ptr->SelectPokeMax = inSelectPokeMax;
	ptr->BoxNumMax = inBoxNumMax;

	if (ptr->SelectPokeMax > SELECT_POKE_APP_MAX){
		GF_ASSERT(0);
		ptr->SelectPokeMax = SELECT_POKE_APP_MAX;
	}
	ptr->Mark = sys_AllocMemory(ptr->HeapID, sizeof(MARK_ICON)*ptr->SelectPokeMax);
	ptr->TouchRect = sys_AllocMemory(ptr->HeapID, sizeof(RECT_HIT_TBL)*(TOUCH_RECT_COMMON_MAX+ptr->SelectPokeMax));

	//キーリンクコントローラのアロック
	ptr->KeyLinkContPtr = KeyLink_Alloc(ptr->HeapID, &ptr->CurrentBox);

	return ptr;
}

//--------------------------------------------------------------------------------------------
/**
 * メモリ解放
 *
 * @param	ptr			ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void POKESEL_Free( POKE_SELECT_WORK_PTR ptr )
{
	int i;

	//キーリンクコントローラ解放
	KeyLink_Free(ptr->KeyLinkContPtr);

	//アクター削除
	DeleteCellActor(ptr);
	//ウィンドウ削除
	DeleteWindow(&ptr->TitleWin, TRUE);
	GF_BGL_BmpWinDel(&ptr->ExitWin);
	DelSelectMsgWin(ptr);


	//スクリーンアーカイブ解放
	sys_FreeMemoryEz(ptr->TemochiBgArc);
	sys_FreeMemoryEz(ptr->BoxBgArc);

	// キャラ転送マネージャー破棄
	CLACT_U_CharManagerDelete(ptr->ResObjTbl[CLACT_U_CHAR_RES]);
	// パレット転送マネージャー破棄
	CLACT_U_PlttManagerDelete(ptr->ResObjTbl[CLACT_U_PLTT_RES]);
	// キャラ・パレット・セル・セルアニメのリソースマネージャー破棄
	for(i=0;i<CLACT_U_RES_MAX;i++){
		CLACT_U_ResManagerDelete(ptr->ResMan[i]);
	}

	// セルアクターセット破棄
	CLACT_DestSet(ptr->ClactSet);

	//ドロップポイント解放
	sys_FreeMemoryEz(ptr->DropPoint);
	// タッチシステムの開放
	TOUCH_SW_FreeWork(ptr->TouchSubWindowSys);
	//タッチ矩形解放
	sys_FreeMemoryEz(ptr->TouchRect);
	//マーカ解放
	sys_FreeMemoryEz(ptr->Mark);

	//タッチフォントアンロード
	FontProc_UnloadFont(FONT_TOUCH);

	// 上下画面を元に戻しておく
	sys.disp3DSW = DISP_3D_TO_MAIN;
	GF_Disp_DispSelect();

	//ブレンドクリア
	G2_BlendNone();

	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME0_M);
	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME1_M);
	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME2_M);
	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME3_M);

	//アプリワーク解放
	sys_FreeMemoryEz(ptr);
}


//--------------------------------------------------------------------------------------------
/**
 * 初期化
 *
 * @param	ptr					ワークポインタ
 * @param	inBGL				BGL
 * @param	pBoxData			ボックスデータ
 * @param	pMyParty			手持ちデータ
 * @param	inItemVisible		アイテム表示するか？
 * @param	inBallVisible		カスタムボール表示するか？
 * @param	inCancelOK			キャンセルできるか？
 * @param	inFirstBox			アプリはじめのボックス番号
 * @param	pAccessFunc			ボックスアクセス関数
 * @param	pGetBoxNameFunc		ボックス名アクセス関数
 * @param	outInfo				アプリリザルト情報バッファ
 * @param	CallBackFunc		選択ポケモン変更時のコールバック関数
 * @param	CallBackWk			コールバックワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void POKESEL_Init(	POKE_SELECT_WORK_PTR ptr, GF_BGL_INI *inBGL,
					void *pBoxData, POKEPARTY *pMyParty,
					const BOOL inItemVisible,
					const BOOL inBallVisible,
					const BOOL inCancelOK,
					const int inFirstBox,
					GET_BOX_POKE_DATA pAccessFunc,
					GET_BOX_NAME	  pGetBoxNameFunc,
					SELECT_RESULT_INFO *outInfo,
					POKE_SEL_CALL_BACK CallBackFunc,
					void *CallBackWk )
{
	//下画面ウインドウシステム初期化
	ptr->TouchSubWindowSys = TOUCH_SW_AllocWork(ptr->HeapID);

	//ポケモンアクセスデータセット
	ptr->AccessWork.BoxData = pBoxData;
	ptr->AccessWork.MyParty = pMyParty;
	//BGLをセット
	ptr->bgl = inBGL;
	//コールバックワークセット
	ptr->CallBackWk = CallBackWk;
	//コールバック関数セット
	ptr->CallBackFunc = CallBackFunc;
	//初期ボックスナンバー
	ptr->CurrentBox = inFirstBox;
	//コールバックテンポラリ
	ptr->TmpBoxNo = -1;
	ptr->TmpBoxPos = -1;
	//キャンセル可・不可セット
	ptr->CancelOK = inCancelOK;
	//ＶＲＡＭ割り当て
//	SetVRAMBank();
	//ＢＧセットアップ
	SetUpBG(ptr->bgl, ptr->HeapID);
	//キャラ・パレットマネージャ初期化
//	InitCharPlttManager();
	//セルアクター初期化・ポケモンアイコンパレット転送
	InitCellActor(ptr);
	//セルアクターヘッダー作成
	MakeCellActorHeader(ptr);
	//ポケモンアイコン以外のアクターを作成
	SetMiscIcon(ptr);
	//Ｖブランク関数実行開始
//	sys_VBlankFuncChange( VBlankFunc, work );
	//ＯＢＪ面ＯＮ
	GF_Disp_GX_VisibleControl(  GX_PLANEMASK_OBJ, VISIBLE_ON );	//メイン画面OBJ面ＯＮ

	//タッチフォントロード
	FontProc_LoadFont(FONT_TOUCH, ptr->HeapID);

	// ウィンドウ枠とパレットをＶＲＡＭへロード
	SystemFontPaletteLoad( PALTYPE_MAIN_BG, SFONT_FRAMECOL * 32, ptr->HeapID);
	//タッチフォント用パレットロード
	SystemFontPaletteLoad( PALTYPE_MAIN_BG, TFONT_FRAMECOL * 32, ptr->HeapID);

	//ビジブルセット
	ptr->ItemVisible = inItemVisible;
	ptr->BallVisible = inBallVisible;

	//キーリンク
	KeyLink_Init(ptr->KeyLinkContPtr, inCancelOK);
	KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_BOX, 0);

	//ドロップポイント作成
	CreateDropPoint(ptr);

	//ボックスアクセス関数セット
	ptr->GetDataFuncTbl.GetBoxPokeData = pAccessFunc;
	//ボックス名取得関数セット
	ptr->GetDataFuncTbl.GetBoxName = pGetBoxNameFunc;

	// ボックス表示ウィンドウ作成
	GF_BGL_BmpWinAdd(ptr->bgl, &(ptr->TitleWin), GF_BGL_FRAME1_M,
			     BOX_TITLE_SX, BOX_TITLE_SY, BOX_TITLE_WIDTH, BOX_TITLE_HEIGHT,
				 FONT_PALNO_NORMAL, BOX_TITLEBASE);
	//「やめる」表示ウィンドウ作成
	GF_BGL_BmpWinAdd(ptr->bgl, &(ptr->ExitWin), GF_BGL_FRAME1_M,
			     EXIT_SX, EXIT_SY, EXIT_WIDTH, EXIT_HEIGHT,
				 FONT_PALNO_TOUCH, EXIT_BASE);
	DrawExit(ptr);		//やめる表示

	//スクリーンセット
	SetScreen(ptr, ptr->bgl, ptr->HeapID);
	//ポケモンセット
	SetPokemonIcon(ptr);
	//リドロー
	RedrawBox(ptr);

	//メッセージ表示
	DispSelectMsg(ptr);

	//パッシブ状態解除（アルファ設定）
	ClearPassive();

	//選択結果格納バッファへのポインタを保存
	ptr->Result = outInfo;

	//シーケンスセット
	ptr->Seq = MAIN_SEQ_POKE_SELECT;

	//キードラッグ状態OFF
	ptr->KeyDrag = FALSE;
	//ドラッグ状態ＯＦＦ
	ptr->TouchDrag = FALSE;
	//タッチトリガー通過フラグＯＦＦ
	ptr->TouchTrgFlg = FALSE;

}

//--------------------------------------------------------------------------------------------
/**
 * Vブランク期間に呼ぶ関数
 *
 * @param	work			ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void POKESEL_DefaultVBlankCallFunc(void *work)
{
	POKE_SELECT_WORK_PTR ptr = (POKE_SELECT_WORK_PTR)work;

	if(ptr->DrawFunc){
		ptr->DrawFunc(ptr->PokeBuf);
		ptr->DrawFunc = NULL;
		//コールバック
		CallBack(ptr);
	}

	// セルアクターVram転送マネージャー実行
	DoVramTransferManager();
	// レンダラ共有OAMマネージャVram転送
	REND_OAMTrans();
	GF_BGL_VBlankFunc(ptr->bgl);
	OS_SetIrqCheckFlag( OS_IE_V_BLANK );
}

//--------------------------------------------------------------------------------------------
/**
 * メイン関数
 *
 * @param	ptr					ワークポインタ
 *
 * @return	SELECT_MAIN_RC		リターンコード
 */
//--------------------------------------------------------------------------------------------
SELECT_MAIN_RC POKESEL_Main(POKE_SELECT_WORK_PTR ptr)
{
	SELECT_MAIN_RC rc;

	switch(ptr->Seq){
	case MAIN_SEQ_POKE_SELECT:
		rc = PokemonSelectMain(ptr);
		break;
	case MAIN_SEQ_SEL_CHECK_READY:
		SelectCheckReady(ptr);
		rc = SELECT_MAIN_RC_NONE;
		break;
	case MAIN_SEQ_SELECT_CHECK:
		PokemonSelectCheck(ptr);
		rc = SELECT_MAIN_RC_NONE;
		break;
	case MAIN_SEQ_SELECT_COPY:
		break;
	case MAIN_SEQ_ENTRY_POKE_CANCEL:
		CancelEntryPokeReady(ptr);
		rc = SELECT_MAIN_RC_NONE;
		break;
	case MAIN_SEQ_ENTRY_POKE_CANCEL_CHECK:
		CancelEntryPokeCheck(ptr);
		rc = SELECT_MAIN_RC_NONE;
		break;
	case MAIN_SEQ_SELECT_END:
		//選択されたポケモンの情報を外部バッファへコピーする
		CopyResult(ptr);
		rc = SELECT_MAIN_RC_END;
		break;
	}

	return rc;
}

//--------------------------------------------------------------------------------------------
/**
 * 選択メイン関数
 *
 * @param	ptr			ワークポインタ
 *
 * @return	SELECT_MAIN_RC			リターンコード
 */
//--------------------------------------------------------------------------------------------
static SELECT_MAIN_RC PokemonSelectMain(POKE_SELECT_WORK_PTR ptr)
{
	int key = 0;
	int selno, seltype;
	SELECT_MAIN_RC rc = SELECT_MAIN_RC_NONE;
	// 選択メイン

	//まず、タッチしているかを判断する
	if ( (!GF_TP_GetCont())&&(!ptr->TouchDrag) ){		//キーコントロール
		//ドラッグ状態ではなく、画面にタッチしていないなら、キー受付
		key = sys.trg;//sys.cont;
		if(key){
			LINK_AREA_ID link_area_id;
			s8 x,y;
			x = 0;
			y = 0;
			//何処にいるかを調べる
			link_area_id  = KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr);
			switch(key){
			case PAD_KEY_LEFT:
				if (link_area_id == LINK_AREA_BOX_NAME){
					//ボックスページ変更
					PushArrowL(ptr);
				}else{
					//ボックスページ変更
					x--;
				}
				break;
			case PAD_KEY_RIGHT:
				if (link_area_id == LINK_AREA_BOX_NAME){
					PushArrowR(ptr);
				}else{
					x++;
				}
				break;
			case PAD_KEY_UP:
				y--;
				break;
			case PAD_KEY_DOWN:
				y++;
				break;
			case PAD_BUTTON_DECIDE:
				rc = ButtonPushFunc( ptr );
				if ( (rc != SELECT_MAIN_RC_NONE) &&
						(rc != SELECT_MAIN_RC_CANCEL)){	//キャンセルのときは既にSEを鳴らしているので対象からはずす
					//SE
					Snd_SePlay(SEQ_SE_DP_DECIDE);
				}
				break;
			case PAD_BUTTON_CANCEL:
				rc = ButtonCancelFunc( ptr );
				if ( (rc != SELECT_MAIN_RC_NONE) &&
						(rc != SELECT_MAIN_RC_CANCEL)){	//キャンセルのときは既にSEを鳴らしているので対象からはずす
					//SE
					Snd_SePlay(SEQ_SE_DP_DECIDE);
				}
				break;
			}
			if ( (x!=0)||(y!=0) ){
				BOOL mv_rc;
				mv_rc = KeyLink_MovePointPosition(ptr->KeyLinkContPtr, x, y);
				MoveCursor(ptr);
				if (mv_rc){
					//SE
					Snd_SePlay(SEQ_SE_DP_SELECT);
				}
			}
		}
	}

	if ( !key && !ptr->KeyDrag){													//タッチコントロール
		if (GF_TP_GetTrg() && (ptr->PokeDrag.State == FALSE)){		//トリガー
			//トリガー通過フラグＯＮ
			ptr->TouchTrgFlg = TRUE;
			selno = GF_TP_RectHitTrg((const RECT_HIT_TBL *)ptr->TouchRect);
			if(selno != RECT_HIT_NONE){
				if(selno < POKEMON_ICON_MAX){											//ボックスエリア
					//手持ちの場合は条件が限定される
					if ((ptr->CurrentBox != MYPARTY_BOX) || (selno < MYPARTY_BOX_SEL_MAX)){
						KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_BOX, selno);
						seltype = SelectPokemon(ptr, selno);
						if (seltype == SELECT_POKEMON_SELECT){
							Snd_SePlay(SEQ_SE_DP_BOX02);
							//ドラッグ開始
							SetDragPokemon(ptr, BOX_POKE_ICON, selno);

							rc = SELECT_MAIN_RC_SELECT;
						}
					}
				}else if( (ICON_DROP_POKEMON <= selno )&&( selno < ICON_TERMINATE) ){	//ドロップエリア
					KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_DROP, selno-ICON_DROP_POKEMON);
					seltype = SelectDropPokemon(ptr, selno-ICON_DROP_POKEMON);
					if (seltype == SELECT_POKEMON_SELECT){
						Snd_SePlay(SEQ_SE_DP_BOX02);
						//ドラッグ開始
						SetDragPokemon(ptr, DROP_POKE_ICON, selno-ICON_DROP_POKEMON);

						rc = SELECT_MAIN_RC_SELECT;
					}
				}else {
					switch(selno){
					case ICON_ARROWL:			//左タッチボタン
						PushArrowL(ptr);
						break;
					case ICON_ARROWR:			//右タッチボタン
						PushArrowR(ptr);
						break;
					case ICON_CANCEL:			//やめるボタン
						//キャンセルが許可されていないならば、処理を抜ける
						if (!ptr->CancelOK){
							break;
						}

						//カーソル位置セット
						{
							VecFx32 vec;
							vec.x = FX32_ONE*BTN_POS_X_TERMINATE;
							vec.y = FX32_ONE*BTN_POS_Y_TERMINATE;
							vec.z = 0;
							CLACT_SetMatrix(ptr->Curssor, &vec);
						}
						KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_EXIT, 0);
						///RequestFadeW(work, WIPE_TYPE_FADEOUT, AGBCARTRIDGE_SEQ_FINISH, seq);
						PushExit(ptr);
						rc = SELECT_MAIN_RC_CANCEL;
						break;
					}
				}//endif(selno < POKEMON_ICON_MAX)

				//コールバック
				CallBack(ptr);
			}//end if(selno != RECT_HIT_NONE)
			ptr->TouchDrag = TRUE;		//トリガーだけどドラッグフラグ立てとく
		}else if (GF_TP_GetCont() && ptr->TouchTrgFlg){	//ベタ
			//ドラッグ処理
			DragPokemon(ptr);	//ドラッグしていなかった場合
			ptr->TouchDrag = TRUE;
		}else{					//タッチしていない
			//ドロップ処理
			DropPokemon(ptr);
			ptr->TouchDrag = FALSE;
			//タッチトリガー通過フラグＯＦＦ
			ptr->TouchTrgFlg = FALSE;
		}
	}

	//選択完了チェック
	if(ptr->Selected == ptr->SelectPokeMax){
		ptr->Seq = MAIN_SEQ_SEL_CHECK_READY;
	}
	return rc;
}

//--------------------------------------------------------------------------------------------
/**
 * 選択ポケモン確認準備
 *
 * @param	ptr			ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SelectCheckReady(POKE_SELECT_WORK_PTR ptr)
{
	// はい／いいえ選択
	TOUCH_SW_PARAM param;

	MI_CpuClear8(&param,sizeof(TOUCH_SW_PARAM));
	param.p_bgl		= ptr->bgl;
	param.bg_frame	= GF_BGL_FRAME0_M;
	param.char_offs	= 512;
	param.pltt_offs 	= 8;
	param.x		= YESNO_X;
	param.y		= YESNO_Y;
	TOUCH_SW_Init(ptr->TouchSubWindowSys, &param );

	//1匹選択と3匹選択で分岐
	if (ptr->SelectPokeMax == 1){
		//現在表示中のメッセージを消す
		DeleteWindow(&ptr->MsgWin, FALSE);
		SetupMsgWindow(ptr,POKE_SEL_ENTRY1, FONT_TALK);
	}else{
		SetupMsgWindow(ptr,POKE_SEL_ENTRY3, FONT_TALK);
	}

	//パッシブ状態
	SetPassive();

	ptr->Seq = MAIN_SEQ_SELECT_CHECK;
}

//--------------------------------------------------------------------------------------------
/**
 * 選択ポケモン確認
 *
 * @param	ptr			ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void PokemonSelectCheck(POKE_SELECT_WORK_PTR ptr)
{
	int selno;
	//確認
    selno = TOUCH_SW_Main( ptr->TouchSubWindowSys );
    switch(selno){
    case TOUCH_SW_RET_YES:		// はい
		//ウィンドウ削除
		DeleteWindow(&ptr->MsgWin, TRUE);
		TOUCH_SW_Reset( ptr->TouchSubWindowSys );

		ptr->Seq = MAIN_SEQ_SELECT_END;
		break;
    case TOUCH_SW_RET_NO:		// いいえ
		//ウィンドウ削除
		DeleteWindow(&ptr->MsgWin, TRUE);
		TOUCH_SW_Reset( ptr->TouchSubWindowSys );
		//最後の1匹を戻す
		ReturnPokeIcon(ptr, ptr->LastDropIndex);
		DispSelectMsg(ptr);

		//パッシブ解除
		ClearPassive();

		//コールバック
		CallBack(ptr);

		ptr->Seq = MAIN_SEQ_POKE_SELECT;
      break;
    }
}

//--------------------------------------------------------------------------------------------
/**
 * 選択ポケモンキャンセル？
 *
 * @param	ptr		ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void CancelEntryPokeReady(POKE_SELECT_WORK_PTR ptr)
{
	// はい／いいえ選択
	TOUCH_SW_PARAM param;

	MI_CpuClear8(&param,sizeof(TOUCH_SW_PARAM));
	param.p_bgl		= ptr->bgl;
	param.bg_frame	= GF_BGL_FRAME0_M;
	param.char_offs	= 512;
	param.pltt_offs 	= 8;
	param.x		= YESNO_X;
	param.y		= YESNO_Y;
	TOUCH_SW_Init(ptr->TouchSubWindowSys, &param );

	SetupMsgWindow(ptr,POKE_SEL_CANCEL, FONT_SYSTEM);

	//パッシブ状態
	SetPassive();

	ptr->Seq = MAIN_SEQ_ENTRY_POKE_CANCEL_CHECK;
}

//--------------------------------------------------------------------------------------------
/**
 * 選択ポケモン確認
 *
 * @param	ptr		ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void CancelEntryPokeCheck(POKE_SELECT_WORK_PTR ptr)
{
	int selno;
	//確認
    selno = TOUCH_SW_Main( ptr->TouchSubWindowSys );
    switch(selno){
    case TOUCH_SW_RET_YES:		// はい
		//ウィンドウ削除
		DeleteWindow(&ptr->MsgWin, TRUE);
		TOUCH_SW_Reset( ptr->TouchSubWindowSys );

		//つかんでるポケモンをエントリーからはずす
		ReturnPokeIcon(ptr, ptr->PokeDrag.TargetIdx);
		//カーソルをつかみ状態から指差し状態へ
		CLACT_AnmChg(ptr->Curssor, CURSSOR_ICON_ANM_OFS);

		//返却
		DropResultFunc(ptr, DROP_RETURN);
		//キードラッグ状態解除
		ptr->KeyDrag = FALSE;

		//パッシブ解除
		ClearPassive();

		//コールバック
		CallBack(ptr);

		ptr->Seq = ptr->Seq = MAIN_SEQ_POKE_SELECT;
		break;
    case TOUCH_SW_RET_NO:		// いいえ
		//ウィンドウ削除
		DeleteWindow(&ptr->MsgWin, TRUE);
		TOUCH_SW_Reset( ptr->TouchSubWindowSys );

		//つかみ状態を解除
		//つかんでるポケモンを戻す（ドロップ失敗とみなす）
		DropResultFunc(ptr ,DROP_NG);

		//パッシブ解除
		ClearPassive();

		ptr->Seq = MAIN_SEQ_POKE_SELECT;
      break;
    }
}



//--------------------------------------------------------------------------------------------
/**
 * 描画関数
 *
 * @param	ptr		ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void POKESEL_Draw(POKE_SELECT_WORK_PTR ptr)
{
	if(ptr->ClactSet!=NULL){
		CLACT_Draw( ptr->ClactSet );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * ボックスアクセス関数セット
 *
 * @param	ptr			ワークポインタ
 * @param	pAccessFunc		ボックスアクセス関数
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void POKESEL_SetBoxAccessFunc(POKE_SELECT_WORK_PTR ptr, GET_BOX_POKE_DATA pAccessFunc)
{
	ptr->GetDataFuncTbl.GetBoxPokeData = pAccessFunc;
}

//------------------------------------------------------------------
/**
 * @brief	セルアクターの初期化
 * @param	ptr		ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void InitCellActor(POKE_SELECT_WORK_PTR ptr)
{
	int i;
	// セルアクター初期化
	ptr->ClactSet = CLACT_U_SetEasyInit( CELL_ACTOR_MAX, &ptr->RendData, ptr->HeapID);
	//サブ画面ディスタンス設定
	CLACT_U_SetSubSurfaceMatrix( &ptr->RendData, 0, SUB_DISTANCE );

	//リソースマネージャー初期化
	for(i=0;i<CLACT_U_RES_MAX;i++){	//リソースマネージャー作成
		ptr->ResMan[i] = CLACT_U_ResManagerInit(3, i, ptr->HeapID);
	}

	//---------上画面用-------------------
	//chara読み込み
	ptr->ResObjTbl[CLACT_U_CHAR_RES] =
		CLACT_U_ResManagerResAddArcChar(ptr->ResMan[CLACT_U_CHAR_RES],
					    ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_box_oam_lz_cngr,
					    1, 0, NNS_G2D_VRAM_TYPE_2DMAIN, ptr->HeapID);

	//pal読み込み
	ptr->ResObjTbl[CLACT_U_PLTT_RES] =
		CLACT_U_ResManagerResAddArcPltt(ptr->ResMan[CLACT_U_PLTT_RES],
					    ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_box_oam_nclr,
					    0, 0, NNS_G2D_VRAM_TYPE_2DMAIN, 4, ptr->HeapID);

	//cell読み込み
	ptr->ResObjTbl[CLACT_U_CELL_RES] =
		CLACT_U_ResManagerResAddArcKindCell(ptr->ResMan[CLACT_U_CELL_RES],
						ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_box_oam_lz_ccer,
						1, 0, CLACT_U_CELL_RES,ptr->HeapID);

	//同じ関数でanim読み込み
	ptr->ResObjTbl[CLACT_U_CELLANM_RES] =
		CLACT_U_ResManagerResAddArcKindCell(ptr->ResMan[CLACT_U_CELLANM_RES],
						ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_box_oam_lz_canr,
						1, 0, CLACT_U_CELLANM_RES,ptr->HeapID);
	// Chara転送
	CLACT_U_CharManagerSetAreaCont( ptr->ResObjTbl[CLACT_U_CHAR_RES] );
	// パレット転送
	CLACT_U_PlttManagerSet( ptr->ResObjTbl[CLACT_U_PLTT_RES] );
	// ポケモンアイコン用パレットを一気に読み込んでVRAM転送する
	ArcUtil_PalSet( ARC_POKEICON, PokeIconPalArcIndexGet(), PALTYPE_MAIN_OBJ, POKEICON_PAL_OFFSET*0x20,
			  0, ptr->HeapID);
}

//------------------------------------------------------------------
/**
 * @brief	セルアクターヘッダの作成
 * @param	ptr		ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void MakeCellActorHeader(POKE_SELECT_WORK_PTR ptr)
{
	// セルアクターヘッダ作成
	CLACT_U_MakeHeader(&ptr->ClActHeader, 0, 0, 0, 0, CLACT_U_HEADER_DATA_NONE, CLACT_U_HEADER_DATA_NONE,
			     0, 0,
			     ptr->ResMan[CLACT_U_CHAR_RES],
				 ptr->ResMan[CLACT_U_PLTT_RES],
			     ptr->ResMan[CLACT_U_CELL_RES],
				 ptr->ResMan[CLACT_U_CELLANM_RES],
			     NULL,NULL);
}

//------------------------------------------------------------------
/**
 * @brief	ドロップポイントの作成
 * @param	ptr			ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void CreateDropPoint(POKE_SELECT_WORK_PTR ptr)
{
	int i;
	int h;
	CLACT_ADD add;
	MakeCLACT_ADD(&add, ptr, NNS_G2D_VRAM_TYPE_2DMAIN );

	ptr->DropPoint = sys_AllocMemory(ptr->HeapID, sizeof(DROP_POINT)*ptr->SelectPokeMax);

	for(i=0;i<ptr->SelectPokeMax;i++){
		h = i;		//0 〜 2
		ptr->DropPoint[i].Top = DROP_POINT_Y_BASE + h * DROP_ICON_Y_OFS;
		ptr->DropPoint[i].Bottom = ptr->DropPoint[i].Top + DROP_POINT_HEIGHT;
		ptr->DropPoint[i].Left = DROP_POINT_X_BASE;
		ptr->DropPoint[i].Right = ptr->DropPoint[i].Left + DROP_POINT_WIDTH;

		ptr->DropPoint[i].Drop = FALSE;

		add.mat.x = FX32_ONE * (DROP_ICON_X_BASE);
		add.mat.y = FX32_ONE * (DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS + DROP_ICON_DRAW_OFS);
		//ドロップポケモンのアイコン登録
		if(ptr->DropIcon[i].Clact == NULL){
			ptr->DropIcon[i].Clact = CLACT_Add(&add);
		}
		CLACT_SetAnmFlag(ptr->DropIcon[i].Clact, 1);
		CLACT_AnmChg( ptr->DropIcon[i].Clact, DROP_POKE_ICON_ANM_OFS+i );
		CLACT_BGPriorityChg( ptr->DropIcon[i].Clact, 1 );
		CLACT_SetDrawFlag( ptr->DropIcon[i].Clact, 0 );
		CLACT_DrawPriorityChg( ptr->DropIcon[i].Clact, PRI_POKE_ICON);

		//タッチ矩形作成
		SetRectHitTable(&ptr->TouchRect[ICON_DROP_POKEMON+i],
					DROP_ICON_X_BASE,
					DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS,
					/*26*/POKEMON_WIDTH, /*28*/POKEMON_HEIGHT);

	}

	//ドロップ禁止パネル
	{
		u8 count = 0;
		for(;i<SELECT_POKE_APP_MAX;i++){
			h = i;		//0 〜 2
			ptr->Panel[count++] = SetOamIcon(ptr,
					(DROP_ICON_X_BASE),
					(DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS),
					PANEL_ICON_ANM_OFS, 1);	// やめる
		}
	}

	//返却トレー矩形作成
	ptr->TrayPoint.Top = DROP_TRAY_Y;
	ptr->TrayPoint.Bottom = DROP_TRAY_Y + DROP_TRAY_H - 1;
	ptr->TrayPoint.Left = DROP_TRAY_X;
	ptr->TrayPoint.Right = DROP_TRAY_X + DROP_TRAY_W - 1;
	ptr->TrayPoint.Drop = FALSE;		//返却トレーに関しては、これは使わない
}

//------------------------------------------------------------------
/**
 * @brief	ドロップポイント捜査
 * @param	ptr		ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static DROP_TYPE CheckDropPoint(POKE_SELECT_WORK_PTR ptr)
{
	int i,j;
	//つかんでいるものが、ボックスアイコンか、ドロップ済みアイコンかで、処理を分岐
	if (ptr->PokeDrag.IconType == BOX_POKE_ICON){		//ボックスアイコン
		for (i=0;i<ptr->SelectPokeMax;i++){
			//すでにドロップ済みかを調べる
			if(!ptr->DropPoint[i].Drop){
				//ドロップ済みではない
				u32 x,y,left,right,top,bottom;
				//ドロップ内チェック
				x = ptr->PokeDrag.Point.x;
				y = ptr->PokeDrag.Point.y;
				left = ptr->DropPoint[i].Left;
				right = ptr->DropPoint[i].Right;
				top = ptr->DropPoint[i].Top;
				bottom = ptr->DropPoint[i].Bottom;
				if ( (( x - left ) < ( right - left ))
					 && (( y - top ) < ( bottom - top )) ){
					Drop(ptr, i);
					return DROP_BOX_TO_AREA;
				}//end if
			}else{
				//ドロップ済み
				u32 x,y,left,right,top,bottom;
				//ドロップ内チェック
				x = ptr->PokeDrag.Point.x;
				y = ptr->PokeDrag.Point.y;
				left = ptr->DropPoint[i].Left;
				right = ptr->DropPoint[i].Right;
				top = ptr->DropPoint[i].Top;
				bottom = ptr->DropPoint[i].Bottom;
				if ( (( x - left ) < ( right - left ))
					 && (( y - top ) < ( bottom - top )) ){
					//ドロップ矩形内
					OS_Printf("ドロップIDX=%d　ポケIDX=%d,ここはすでにポケがいる\n", i, ptr->DropIconData[i].PokeIndex);
					//まず、既にいるポケをボックスへ返却する
					ReturnPokeIcon(ptr, i);
					//空いたところにつかんでるポケをドロップ
					Drop(ptr, i);
					return DROP_BOX_TO_AREA;
				}
			}//end if (!ptr->DropPoint[i].Drop)
		}//end for
	}else if(ptr->PokeDrag.IconType == DROP_POKE_ICON){	//ドロップ済みアイコン
		//返却トレー以外は、元に位置に戻す
		u32 x,y,left,right,top,bottom;
		//ドロップ内チェック
		x = ptr->PokeDrag.Point.x;
		y = ptr->PokeDrag.Point.y;
		left = ptr->TrayPoint.Left;
		right = ptr->TrayPoint.Right;
		top = ptr->TrayPoint.Top;
		bottom = ptr->TrayPoint.Bottom;
		if ( (( x - left ) < ( right - left ))
			 && (( y - top ) < ( bottom - top )) ){
			VecFx32 vec;
			//ドロップ
			OS_Printf("%d::ポケモン返却！！\n",ptr->PokeDrag.TargetIdx);
			ReturnPokeIcon(ptr, ptr->PokeDrag.TargetIdx);
			//コールバック
			CallBack(ptr);
			return DROP_RETURN;
		}
		//ドロップエリア内移動かをチェック
		for (i=0;i<ptr->SelectPokeMax;i++){
			//すでにドロップ済みかを調べる
			if(!ptr->DropPoint[i].Drop){
				//ドロップ済みではない
				u32 x,y,left,right,top,bottom;
				//ドロップ内チェック
				x = ptr->PokeDrag.Point.x;
				y = ptr->PokeDrag.Point.y;
				left = ptr->DropPoint[i].Left;
				right = ptr->DropPoint[i].Right;
				top = ptr->DropPoint[i].Top;
				bottom = ptr->DropPoint[i].Bottom;
				if ( (( x - left ) < ( right - left ))
					 && (( y - top ) < ( bottom - top )) ){
					//ポケの場所移動
					OS_Printf("ポケ移動");
					Move(ptr, ptr->PokeDrag.TargetIdx, i);
					return DROP_AREA_TO_AREA;
				}//end if
			}
		}
	}else{
		GF_ASSERT(0);
	}

	return DROP_NG;
}

//------------------------------------------------------------------
/**
 * @brief	ドロップ処理
 * @param	ptr		ワークポインタ
 * @param	inIdx	インデックス
 * @return	NONE
 */
//------------------------------------------------------------------
static void Drop(POKE_SELECT_WORK_PTR ptr, const u8 inIdx)
{
	u8 j;
	VecFx32 vec;
	//ドロップ
	OS_Printf("%d::ドロップ！！\n",inIdx);
	//SE
	Snd_SePlay(SEQ_SE_DP_BOX01);
	ptr->DropPoint[inIdx].Drop = TRUE;
	//ドロップポイントのリドロー
	RedrawDropPoint(ptr, inIdx, ptr->PokeDrag.TargetIdx, FALSE);
	for(j = 0; j < ptr->SelectPokeMax; j++){
		if(ptr->Mark[j].PokeNo == POKEMON_NOSELECT){
			// 元のポケモンから座標情報を得て(ポインタを得るだけ)
			vec = ptr->PokeDrag.OrgVec;
			vec.x -= FX32_ONE * 8;
			vec.y -= FX32_ONE * 4;
			CLACT_SetMatrix(ptr->Mark[j].Icon, &vec);
			// アイコンの表示フラグをON
			CLACT_SetDrawFlag(ptr->Mark[j].Icon, 1);
			ptr->Mark[j].PokeNo = ptr->PokeDrag.TargetIdx;
			ptr->Mark[j].BoxNo = ptr->CurrentBox;
			ptr->Selected++;
			//半透明化
			CLACT_ObjModeSet( ptr->Icon[ptr->PokeDrag.TargetIdx].Clact, GX_OAM_MODE_XLU );
			//ドロップしたアイコンの情報を保存しておく
			ptr->DropIconData[inIdx].PokeIndex = ptr->PokeDrag.TargetIdx;
			ptr->DropIconData[inIdx].BoxIndex = ptr->CurrentBox;
			ptr->DropIconData[inIdx].MarkIndex = j;
			ptr->DropIconData[inIdx].Valid = TRUE;

			ptr->LastDropIndex = inIdx;
			break;
		}
	}//end for
}

//------------------------------------------------------------------
/**
 * @brief	ドロップエリア移動処理
 * @param	ptr		ワークポインタ
 * @param	inOrgIdx	移動元インデックス
 * @param	inDstIdx	移動先インデックス
 * @return	NONE
 */
//------------------------------------------------------------------
static void Move(POKE_SELECT_WORK_PTR ptr, const u8 inOrgIdx, const u8 inDstIdx)
{
	OS_Printf("移動：%d→%d\n",inOrgIdx,inDstIdx);
	//SE
	Snd_SePlay(SEQ_SE_DP_BOX01);
	//--移動前データを無効に
	ptr->DropIconData[inOrgIdx].Valid = FALSE;
	//ドロップ枠を空ける
	CLACT_SetDrawFlag( ptr->DropIcon[inOrgIdx].Clact, 0 );
	ptr->DropPoint[inOrgIdx].Drop = FALSE;


	//--ドロップ
	ptr->DropPoint[inDstIdx].Drop = TRUE;
	OS_Printf("org=%d\n",inOrgIdx);
	//ドロップポイントのリドロー
	RedrawDropPoint(ptr, inDstIdx, inOrgIdx/*ptr->DropIconData[inOrgIdx].PokeIndex*/, TRUE);
	//移動元アイコン情報を移動先アイコン情報にコピー
	ptr->DropIconData[inDstIdx].PokeIndex = ptr->DropIconData[inOrgIdx].PokeIndex;
	ptr->DropIconData[inDstIdx].BoxIndex = ptr->DropIconData[inOrgIdx].BoxIndex;
	ptr->DropIconData[inDstIdx].MarkIndex = ptr->DropIconData[inOrgIdx].MarkIndex;
	ptr->DropIconData[inDstIdx].Valid = TRUE;
	OS_Printf("移動によるデータコピー%d %d %d\n",
			ptr->DropIconData[inDstIdx].PokeIndex,
			ptr->DropIconData[inDstIdx].BoxIndex,
			ptr->DropIconData[inDstIdx].MarkIndex
			);
	ptr->LastDropIndex = inDstIdx;


}

//------------------------------------------------------------------
/**
 * @brief	ポケモンアイコン以外のアクターを作成
 * @param	ptr		ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void SetMiscIcon(POKE_SELECT_WORK_PTR ptr)
{
	int i;

	SetRectHitTable(&ptr->TouchRect[ICON_CANCEL],
							BTN_POS_X_TERMINATE, BTN_POS_Y_TERMINATE, 50, 32);
	ptr->Cancel = SetOamIcon(ptr, BTN_POS_X_TERMINATE, BTN_POS_Y_TERMINATE,
							CANCEL_ICON__ANM_OFS, 1);	// やめる
	CLACT_BGPriorityChg(ptr->Cancel, 3);	//プライオリティを最下層に

	if (!ptr->CancelOK){
		//やめるボタン非表示
		CLACT_SetDrawFlag(ptr->Cancel, FALSE);
	}

	SetRectHitTable(&ptr->TouchRect[ICON_ARROWR], BTN_POS_X_ARROWR, BTN_POS_Y_ARROWR, 32, 32);
	ptr->ArrowR = SetOamIcon(ptr, BTN_POS_X_ARROWR, BTN_POS_Y_ARROWR,
							R_ARROW_ICON_ANM_OFS, 1);	// 右→

	SetRectHitTable(&ptr->TouchRect[ICON_ARROWL],  BTN_POS_X_ARROWL, BTN_POS_Y_ARROWL, 32, 32);
	ptr->ArrowL = SetOamIcon(ptr,  BTN_POS_X_ARROWL, BTN_POS_Y_ARROWL, L_ARROW_ICON_ANM_OFS, 1);	// 左←

	ptr->Smog = SetOamIcon(ptr,  0, 0, SMOG_ANM_OFS, 0);

	ptr->TouchRect[ICON_TERMINATE].rect.top = RECT_HIT_END;

	// 決定アイコンの登録
	for(i = 0; i < ptr->SelectPokeMax; i++){
		ptr->Mark[i].Icon = SetOamIcon(ptr, 36*i, 64, DECIDE_ICON_ANM_OFS, 0);
		ptr->Mark[i].PokeNo = POKEMON_NOSELECT;
		ptr->Mark[i].BoxNo = ptr->BoxNumMax;
		CLACT_DrawPriorityChg( ptr->Mark[i].Icon, PRI_MARK );
	}
	ptr->Selected = 0;

	//カーソル
	ptr->Curssor = SetOamIcon(ptr, POKEMON_BASEX, POKEMON_BASEY, CURSSOR_ICON_ANM_OFS, 1);	// カーソル
	CLACT_BGPriorityChg(ptr->Curssor, 1);
	CLACT_DrawPriorityChg( ptr->Curssor, PRI_CURSSOR );
}

//------------------------------------------------------------------
/**
 * @brief	CLACT_ADDの雛形を作成
 * @param	add				アクターアッドポインタ
 * @param	ptr				ワークポインタ
 * @param	param			パラム
 *
 * @return	NONE
 */
//------------------------------------------------------------------
static void MakeCLACT_ADD(CLACT_ADD *add, POKE_SELECT_WORK_PTR ptr, int param)
{
  add->ClActSet		= ptr->ClactSet;
  add->ClActHeader	= &ptr->ClActHeader;
  add->mat.z		= 0;
  add->sca.x		= FX32_ONE;
  add->sca.y		= FX32_ONE;
  add->sca.z		= FX32_ONE;
  add->rot		= 0;
  add->pri		= PRI_DEFAULT;
  add->DrawArea		= param;
  add->heap		= ptr->HeapID;
}

//------------------------------------------------------------------
/**
 * @brief	ポケモン以外のアイコンを登録
 * @param	ptr			ワークポインタ
 * @param	x			X座標
 * @param	y			Y座標
 * @param	anim		アニメするか？
 * @param	flag		ドローフラグ
 *
 * @return	CLACT_WORK_PTR		アクターワークポインタ
 */
//------------------------------------------------------------------
static CLACT_WORK_PTR SetOamIcon(POKE_SELECT_WORK_PTR ptr, int x, int y, int anim, int flag)
{
	CLACT_ADD add;
	CLACT_WORK_PTR p;

	MakeCLACT_ADD(&add, ptr, NNS_G2D_VRAM_TYPE_2DMAIN );
	add.mat.x = FX32_ONE * x;
	add.mat.y = FX32_ONE * y;
	add.pri   = PRI_BUTTON;
	p = CLACT_Add(&add);
	CLACT_SetAnmFlag(p, 1);
	CLACT_AnmChg(p, anim);
	CLACT_BGPriorityChg(p, 1);
	CLACT_SetDrawFlag(p, flag);
	return p;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	スクリーンセット
 *
 * @param	ptr				ワークポインタ
 * @param	ini				BGL
 * @param	inHeapID		ヒープID
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetScreen(POKE_SELECT_WORK_PTR ptr, GF_BGL_INI * ini, const int inHeapID)
{
	// メイン画面スクリーン１
	ArcUtil_ScrnSet(ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_box_lz_cscr, ini,
			  GF_BGL_FRAME2_M, 0, 32*24*2, 1, inHeapID);

	GF_BGL_ScrPalChange(ini, GF_BGL_FRAME2_M, 0, 0, 32, 24, 1);
	GF_BGL_LoadScreenReq(ini, GF_BGL_FRAME2_M);

	//　メイン画面メッセージウィンドウ
	ArcUtil_ScrnSet(ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_win_lz_cscr, ini,
			  GF_BGL_FRAME3_M, 0, 32*24*2, 1, inHeapID);

	GF_BGL_ScrPalChange(ini, GF_BGL_FRAME3_M, 0, 0, 32, 24, 1);
	GF_BGL_LoadScreenReq(ini, GF_BGL_FRAME3_M);

	//手持ちポケスクリーン
	ptr->TemochiBgArc = ArcUtil_ScrnDataGet(ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_mine_lz_cscr,
						TRUE, &ptr->TemochiScrnData, inHeapID);
	//ボックススクリーン
	ptr->BoxBgArc = ArcUtil_ScrnDataGet(ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_box_lz_cscr,
						TRUE, &ptr->BoxScrnData, inHeapID);

	//ウィンドウはじめ非表示
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG3, VISIBLE_OFF );
}

//------------------------------------------------------------------
/**
 * @brief	RECT_HIT_TBLを登録
 * @param	rect			矩形テーブル
 * @param	x				X座標
 * @param	y				Y座標
 * @param	sizx			横幅
 * @rparam	sizy			縦幅
 *
 * @return	NONE
 */
//------------------------------------------------------------------
static void SetRectHitTable(RECT_HIT_TBL *rect, int x, int y, int sizx, int sizy)
{
  rect->rect.top    = y - sizy / 2;
  rect->rect.left   = x - sizx / 2;
  rect->rect.bottom = y + sizy / 2;
  rect->rect.right  = x + sizx / 2;
}

//------------------------------------------------------------------
/**
 * @brief	画面にポケモンを３０個並べる
 * @param	ptr		ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void SetPokemonIcon(POKE_SELECT_WORK_PTR ptr)
{
	int index, x, y;
	CLACT_ADD add;

	MakeCLACT_ADD(&add, ptr,NNS_G2D_VRAM_TYPE_2DMAIN );

	index = 0;
	for(y = 0; y < 5; y++){
		for(x = 0; x < 6; x++){

			SetRectHitTable(&ptr->TouchRect[index],
					x * POKEMON_WIDTH  + POKEMON_BASEX,
					y * POKEMON_HEIGHT + POKEMON_BASEY,
					/*26*/POKEMON_WIDTH, /*28*/POKEMON_HEIGHT);
			add.mat.x = FX32_ONE * (x * POKEMON_WIDTH  + POKEMON_BASEX);
			add.mat.y = FX32_ONE * (y * POKEMON_HEIGHT + POKEMON_BASEY);
			// ポケモンのアイコン登録
			if(ptr->Icon[index].Clact == NULL){
				ptr->Icon[index].Clact = CLACT_Add(&add);
			}
			CLACT_SetAnmFlag(ptr->Icon[index].Clact, 1);
			CLACT_AnmChg( ptr->Icon[index].Clact, POKE_ICON_ANM_OFS+index );
		    CLACT_BGPriorityChg( ptr->Icon[index].Clact, 1 );
			CLACT_SetDrawFlag( ptr->Icon[index].Clact, 0 );
			CLACT_DrawPriorityChg( ptr->Icon[index].Clact, /*100+index*/PRI_POKE_ICON);

			index++;
		}
	}

	{
		//常時半透明ポケモン
		add.mat.x = FX32_ONE * POKEMON_BASEX;
		add.mat.y = FX32_ONE * POKEMON_BASEY;
		if(ptr->Ghost.Clact == NULL){
			ptr->Ghost.Clact = CLACT_Add(&add);
		}
		CLACT_SetAnmFlag(ptr->Ghost.Clact, 1);
		CLACT_AnmChg( ptr->Ghost.Clact, GHOST_ICON_ANM_OFS );
		CLACT_BGPriorityChg( ptr->Ghost.Clact, 1 );
		CLACT_SetDrawFlag( ptr->Ghost.Clact, 0 );
		CLACT_DrawPriorityChg( ptr->Ghost.Clact, PRI_GHOST_POKE);

		//半透明
		CLACT_ObjModeSet( ptr->Ghost.Clact, GX_OAM_MODE_XLU );

	}
}

//------------------------------------------------------------------
/**
 * @brief	ボックスの再表示
 * @param	ptr				ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void RedrawBox(POKE_SELECT_WORK_PTR ptr)
{
	if (ptr->CurrentBox == MYPARTY_BOX){
		RedrawPokemonMyParty(ptr);
	}else{
		RedrawPokemonBox(ptr);
	}
}

//------------------------------------------------------------------
/**
 * @brief	指定ボックスのポケモンを画面に表示
 * @param	ptr			ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void RedrawPokemonBox(POKE_SELECT_WORK_PTR ptr)
{
	int i;
	void *buf;
	ARCHANDLE* handle;
	BOX_POKE_DATA data;

	handle = ArchiveDataHandleOpen( ARC_POKEICON, ptr->HeapID);
	buf = sys_AllocMemoryLo(ptr->HeapID, 4096);
	// ポケモンアイコンの表示
	for(i = 0; i < POKEMON_ICON_MAX; i++){
		//通常ＯＢＪ
		CLACT_ObjModeSet( ptr->Icon[i].Clact, GX_OAM_MODE_NORMAL );
		if( ptr->GetDataFuncTbl.GetBoxPokeData(ptr->AccessWork.BoxData, ptr->CurrentBox, i, &data) ){

			ptr->Icon[i].PokeData = data;

			TransPokeIconCharaPal(&data, ptr->PokeBuf, i,
					ptr->Icon[i].Clact, buf, handle, POKEICON_VRAM_OFFSET);
			//タマゴならば、半透明表示
			if (data.Egg){
				CLACT_ObjModeSet( ptr->Icon[i].Clact, GX_OAM_MODE_XLU );
			}else{	//通常ＯＢＪ
				CLACT_ObjModeSet( ptr->Icon[i].Clact, GX_OAM_MODE_NORMAL );
			}
		}else {
			TransPokeIconCharaPal(&data, ptr->PokeBuf, i
					, NULL, buf, handle, POKEICON_VRAM_OFFSET);
			CLACT_SetDrawFlag( ptr->Icon[i].Clact, 0 );
		}
	}
	sys_FreeMemoryEz(buf);
	ArchiveDataHandleClose( handle );


	// ポケモンアイコンの転送関数を定義
	ptr->DrawFunc = TransPokeIconFinish;

	// ボックスのタイトル表示
	DrawBoxTitle(ptr, ptr->CurrentBox);
	// 選択アイコンを反映
	CheckSelectPokemonIcon(ptr);
	//BGフィル
	GF_BGL_ScrWriteFree(ptr->bgl, GF_BGL_FRAME2_M,
				0, 0, FILL_BOX_W, FILL_BOX_H,
				&ptr->BoxScrnData->rawData,
				0, 0, 32, 24 );
	GF_BGL_LoadScreenV_Req(ptr->bgl, GF_BGL_FRAME2_M);
}

//------------------------------------------------------------------
/**
 * @brief	手持ちポケモンを画面に表示
 * @param	ptr			ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void RedrawPokemonMyParty(POKE_SELECT_WORK_PTR ptr)
{
	int i;
	void *buf;
	ARCHANDLE* handle;
	BOX_POKE_DATA data;
	u8 party_count;

	handle = ArchiveDataHandleOpen( ARC_POKEICON, ptr->HeapID);
	buf = sys_AllocMemoryLo(ptr->HeapID, 4096);

	// ポケモンアイコンの表示
	party_count = PokeParty_GetPokeCount(ptr->AccessWork.MyParty);
	for(i = 0; i < party_count; i++){
		GetMyPartyPokeData( ptr, i, &data );

		ptr->Icon[i].PokeData = data;

		// ポケモンのフォルムナンバーを取得(これはDSのmonsnoで判定)
		TransPokeIconCharaPal(&data, ptr->PokeBuf, i,
				ptr->Icon[i].Clact, buf, handle, POKEICON_VRAM_OFFSET);
///		CLACT_SetDrawFlag( ptr->Icon[i].Clact, 1 );
		//タマゴならば、半透明表示
		if (data.Egg){
			CLACT_ObjModeSet( ptr->Icon[i].Clact, GX_OAM_MODE_XLU );
		}else{	//通常ＯＢＪ
			CLACT_ObjModeSet( ptr->Icon[i].Clact, GX_OAM_MODE_NORMAL );
		}
	}
	//残りを埋める
	data.MonsNo = 0;
	data.Egg = 0;
	data.Form = 0;
	data.Item = 0;
	data.Ball = 0;
	for (;i < POKEMON_ICON_MAX; i++ ){
		TransPokeIconCharaPal(&data, ptr->PokeBuf, i,
				NULL, buf, handle, POKEICON_VRAM_OFFSET);
		CLACT_SetDrawFlag( ptr->Icon[i].Clact, 0 );
	}

	sys_FreeMemoryEz(buf);
	ArchiveDataHandleClose( handle );


	// ポケモンアイコンの転送関数を定義
	ptr->DrawFunc = TransPokeIconFinish;

	// 手持ちポケモン文字列表示
	DrawBoxTitle(ptr, ptr->CurrentBox);
	// 選択アイコンを反映
	CheckSelectPokemonIcon(ptr);
	//BGフィル
	GF_BGL_ScrWriteFree(ptr->bgl, GF_BGL_FRAME2_M,
				0, 0, FILL_BOX_W, FILL_BOX_H,
				&ptr->TemochiScrnData->rawData,
				0, 0, FILL_BOX_W, FILL_BOX_H );
	GF_BGL_LoadScreenV_Req(ptr->bgl, GF_BGL_FRAME2_M);
}

//------------------------------------------------------------------
/**
 * @brief	ドロップポイントのポケモンを画面に表示
 * @param	ptr				ワークポインタ
 * @param	inIndex			ドロップインデックス
 * @param	inPokeIdx		ポケモンインデックス
 * @param	move			ドロップエリア間の移動か？
 *
 * @return	NONE
 */
//------------------------------------------------------------------
static void RedrawDropPoint(POKE_SELECT_WORK_PTR ptr, const u8 inIndex, const u8 inPokeIdx, const BOOL move)
{
	int i;
	void *buf;
	ARCHANDLE* handle;
	BOX_POKE_DATA data;

	handle = ArchiveDataHandleOpen( ARC_POKEICON, ptr->HeapID);
	buf = sys_AllocMemoryLo(ptr->HeapID, 4096);

	//バッファクリア
	for(i = 0; i < POKEMON_ICON_MAX; i++){
		POKEBUF *pbuf = ptr->PokeBuf + i;
		pbuf->Icon = NULL;
	}

	if (move){
		ptr->DropIcon[inIndex].PokeData = ptr->DropIcon[inPokeIdx].PokeData;
		TransPokeIconCharaPal(&ptr->DropIcon[inPokeIdx].PokeData, ptr->PokeBuf, inIndex,
				ptr->DropIcon[inIndex].Clact, buf, handle, DROP_POKEICON_VRAM_OFFSET);
	}else{
		ptr->DropIcon[inIndex].PokeData = ptr->Icon[inPokeIdx].PokeData;
		TransPokeIconCharaPal(&ptr->Icon[inPokeIdx].PokeData, ptr->PokeBuf, inIndex,
				ptr->DropIcon[inIndex].Clact, buf, handle, DROP_POKEICON_VRAM_OFFSET);
	}

	sys_FreeMemoryEz(buf);
	ArchiveDataHandleClose( handle );


	// ポケモンアイコンの転送関数を定義
	ptr->DrawFunc = TransPokeIconFinish;
}

//------------------------------------------------------------------
/**
 * @brief	ポケモンアイコン転送
 * @param	pbuf			バッファ
 * @return	NONE
 */
//------------------------------------------------------------------
static void TransPokeIconFinish(POKEBUF *pbuf)
{
	int i;
//  POKEBUF *pbuf = _PokeBufPtr;
	for(i = 0; i < POKEMON_ICON_MAX; i++, pbuf++){
		if(pbuf->Icon){
			// キャラクター転送
			DC_FlushRange(pbuf->CharBuf, POKEICON_TRANS_SIZE);
			GX_LoadOBJ(pbuf->CharBuf, pbuf->Adrs, POKEICON_TRANS_SIZE);
			// パレット設定
			//CLACT_PaletteNoChg(pbuf->Icon, pbuf->PalNo);
			//↑※この関数はリクエスト関数なので、ここでコールしても実は遅い。
			//アイコンのキャラをバッファに転送するところでコールするように変更。

			CLACT_SetDrawFlag( pbuf->Icon, 1 );
		}
	}
}

//------------------------------------------------------------------
/**
 * @brief	指定したアイコンの横に決定アイコンを制御
 * @param	ptr			コントロールポインタ
 * @param	inIndex		インデックス
 * @return	NONE
 */
//------------------------------------------------------------------
static int SelectPokemon(POKE_SELECT_WORK_PTR ptr, int inIndex)
{
	//カーソル移動
	{
		const VecFx32 *vec;
		vec = CLACT_GetMatrix(ptr->Icon[inIndex].Clact);
		CLACT_SetMatrix(ptr->Curssor, vec);
	}

	return CheckSelPoke(ptr, inIndex);
}

//------------------------------------------------------------------
/**
 * @brief	指定したインデックスのポケモンの状態
 * @param	ptr			コントロールポインタ
 * @param	inIndex		インデックス
 * @return	int  状態
 */
//------------------------------------------------------------------
static int CheckSelPoke(POKE_SELECT_WORK_PTR ptr, int inIndex)
{
	int i, sel;
	int rc;

	// 空白のチェック
	if(ptr->Icon[inIndex].Clact && CLACT_GetDrawFlag(ptr->Icon[inIndex].Clact) == FALSE){
		return SELECT_POKEMON_NOMONS;
	}

	//タマゴ選択は無効
	if (ptr->Icon[inIndex].PokeData.Egg){
		return SELECT_POKEMON_NOMONS;
	}

	// すでに選択済みなのかを調べる
	for(sel = -1, i = 0; sel == -1 && i < ptr->SelectPokeMax; i++){
		if(ptr->Mark[i].BoxNo == ptr->CurrentBox &&
				ptr->Mark[i].PokeNo == inIndex){
			sel = i;
		}
	}

	if(sel == -1){
		// すでに規定数が選択されていたら何もしない
	    if(ptr->Selected == ptr->SelectPokeMax){
			return SELECT_POKEMON_FULL;
		}

		for(i = 0; i < ptr->SelectPokeMax; i++){
			if(ptr->Mark[i].PokeNo == POKEMON_NOSELECT){
				return SELECT_POKEMON_SELECT;
			}
		}//end for
	}

	return SELECT_POKEMON_CANCEL;
}

//------------------------------------------------------------------
/**
 * @brief	選択済みポケモンアイコン制御
 * @param	ptr			コントロールポインタ
 * @param	inIndex		インデックス
 * @return	NONE
 */
//------------------------------------------------------------------
static int SelectDropPokemon(POKE_SELECT_WORK_PTR ptr, int inIndex)
{
	int rc;

	rc = CheckSelDropPoke(ptr, inIndex);

	if ( inIndex >= ptr->SelectPokeMax ){
		return  rc;
	}

	//カーソル移動
	{
		const VecFx32 *vec;
		vec = CLACT_GetMatrix(ptr->DropIcon[inIndex].Clact);
		CLACT_SetMatrix(ptr->Curssor, vec);
	}

	return rc;
}

//------------------------------------------------------------------
/**
 * @brief	指定したインデックスのポケモンの状態
 * @param	ptr			コントロールポインタ
 * @param	inIndex		インデックス
 * @return	int  状態
 */
//------------------------------------------------------------------
static int CheckSelDropPoke(POKE_SELECT_WORK_PTR ptr, int inIndex)
{
	int rc;

	//インデックス範囲外チェック
	if (inIndex >= ptr->SelectPokeMax){
		//範囲外
		return SELECT_POKEMON_NOMONS;
	}

	// 空白のチェック
	if(ptr->DropIcon[inIndex].Clact && CLACT_GetDrawFlag(ptr->DropIcon[inIndex].Clact) == FALSE){
		return SELECT_POKEMON_NOMONS;
	}

	return SELECT_POKEMON_SELECT;
}

//------------------------------------------------------------------
/**
 * @brief	指定したアイコンの横に決定アイコンを制御
 * @param	ptr			ワークポインタ
 * @param	inIconType		アイコンタイプ
 * @param	inIndex			対象インデックス
 * @return	NONE
 */
//------------------------------------------------------------------
static void SetDragPokemon(POKE_SELECT_WORK_PTR ptr, POKE_ICON_TYPE inIconType, int inIndex)
{
	//カレントの確認。同一であればドラッグできるとみなす。ただし、すでにエントリーしているものはドラッグできない
	const VecFx32 *vec;

	POKEMON_ICON *icon_tbl;

	//ドラッグ状態
	ptr->PokeDrag.State = TRUE;
	//ドラッグ対象を記憶
	ptr->PokeDrag.TargetIdx = inIndex;

	//アイコンタイプ保存
	ptr->PokeDrag.IconType = inIconType;

	//アイコンテーブルをセット
	if (inIconType == BOX_POKE_ICON){
		icon_tbl = ptr->Icon;
		ptr->PokeDrag.IconTbl = ptr->Icon;
	}else if (inIconType == DROP_POKE_ICON){
		icon_tbl = ptr->DropIcon;
		ptr->PokeDrag.IconTbl = ptr->DropIcon;
	}else{
		GF_ASSERT(0);
	}
	//座標保存
	vec = CLACT_GetMatrix(icon_tbl[inIndex].Clact);
	ptr->PokeDrag.OrgVec = *vec;

	//カーソルつかみ状態にする
	CLACT_AnmChg(ptr->Curssor, CURSSOR_GRASP_ICON_ANM_OFS);
	//プライオリティ変更
	CLACT_DrawPriorityChg( ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact, PRI_DRAG_POKE_ICON);

	//ゴースト表示
	if (inIconType == BOX_POKE_ICON){
		int i;
		void *buf;
		ARCHANDLE* handle;
		const VecFx32 *ghost_vec = CLACT_GetMatrix(ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact);

		//バッファクリア
		for(i = 0; i < POKEMON_ICON_MAX; i++){
			POKEBUF *pbuf = ptr->PokeBuf + i;
			pbuf->Icon = NULL;
		}

		handle = ArchiveDataHandleOpen( ARC_POKEICON, ptr->HeapID);
		buf = sys_AllocMemoryLo(ptr->HeapID, 4096);

		TransPokeIconCharaPal(&ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].PokeData,
				ptr->PokeBuf, 0,
				ptr->Ghost.Clact, buf, handle, GHOST_POKEICON_VRAM_OFFSET);

		//ポケモン座標
		CLACT_SetMatrix(ptr->Ghost.Clact, ghost_vec);

		//表示
		CLACT_SetDrawFlag( ptr->Ghost.Clact, 1 );

		sys_FreeMemoryEz(buf);
		ArchiveDataHandleClose( handle );

		// ポケモンアイコンの転送関数を定義
		ptr->DrawFunc = TransPokeIconFinish;
	}

	OS_Printf("ドラッグ状態\n");

}

//------------------------------------------------------------------
/**
 * @brief	指定したアイコンの横に決定アイコンを制御
 * @param	ptr				ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void DragPokemon(POKE_SELECT_WORK_PTR ptr)
{
	//現在ポケモンをドラッグしているか？
	if (ptr->PokeDrag.State){
		VecFx32 vec;
		u32 x,y;
		//タッチ座標を取得
		GF_TP_GetPointCont(&x, &y);
		vec.x = x * FX32_ONE;
		vec.y = y * FX32_ONE;
		vec.z = 0;
		{
			VecFx32 poke_vec;
			poke_vec = vec;
			poke_vec.y -= GRASP_OFS;
			//ドラッグ中。対象ポケモンを移動
			CLACT_SetMatrix(ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact, &poke_vec);
		}

		//カーソル移動
		CLACT_SetMatrix(ptr->Curssor, &vec);

		//ドラッグポイントの保存
		ptr->PokeDrag.Point.x = x;
		ptr->PokeDrag.Point.y = y;

		OS_Printf("point:%d,%d\n",x,y);
	}
}

//------------------------------------------------------------------
/**
 * @brief	ポケモンドロップ
 * @param	ptr				ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void DropPokemon(POKE_SELECT_WORK_PTR ptr)
{
	if (ptr->PokeDrag.State){
		DROP_TYPE rc;
		VecFx32 vec;
		//ドロップポイント捜査
		rc = CheckDropPoint(ptr);

		DropResultFunc(ptr ,rc);
	}
}

//------------------------------------------------------------------
/**
 * @brief	ポケモンドロップ結果
 * @param	ptr		ポケモン選択ワークポインタ
 * @param	inRC	ドロップ結果
 *
 * @return	none
 */
//------------------------------------------------------------------
static void DropResultFunc(POKE_SELECT_WORK_PTR ptr, const DROP_TYPE inRC)
{
	VecFx32 vec;
	if (inRC != DROP_NG){
		u8 idx;
		if (ptr->PokeDrag.IconType == DROP_POKE_ICON){
			if ( inRC == DROP_RETURN ){		//返却した場合
				vec = ptr->PokeDrag.OrgVec;
				idx = ptr->PokeDrag.TargetIdx;
			}else{
				u8 h;
				h = ptr->LastDropIndex;		//0 〜 2
				vec.x = FX32_ONE * (DROP_ICON_X_BASE);
				vec.y = FX32_ONE * (DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS + DROP_ICON_DRAW_OFS);
				vec.z = 0;
				idx = ptr->LastDropIndex;
			}
		}else{
			u8 h;
			h = ptr->LastDropIndex;		//0 〜 2
			vec.x = FX32_ONE * (DROP_ICON_X_BASE);
			vec.y = FX32_ONE * (DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS + DROP_ICON_DRAW_OFS);
			vec.z = 0;
			idx = ptr->LastDropIndex;
		}
		//キーコントロールエリアをドロップエリアに変更
		KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_DROP, idx);
	}else{
		vec = ptr->PokeDrag.OrgVec;
		if (ptr->PokeDrag.IconType == DROP_POKE_ICON){
			//キーコントロールエリアをドロップエリアに変更
			KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_DROP, ptr->PokeDrag.TargetIdx);
		}else{
			//キーコントロールエリアをボックスエリアに変更
			KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_BOX, ptr->PokeDrag.TargetIdx);
		}
	}

	{
		VecFx32 icon_vec;
		//ポケモンアイコンをもとの位置へ
		CLACT_SetMatrix(ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact, &ptr->PokeDrag.OrgVec);
		CLACT_DrawPriorityChg(ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact, PRI_POKE_ICON);
	}

	//カーソル
	CLACT_SetMatrix(ptr->Curssor, &vec);
	CLACT_AnmChg(ptr->Curssor, CURSSOR_ICON_ANM_OFS);

	//キードラッグ状態か？
	if (ptr->KeyDrag){
		ptr->KeyDrag = FALSE;
	}

	//ドラッグ状態をクリア
	{
		ptr->PokeDrag.State = FALSE;
		ptr->PokeDrag.TargetIdx = -1;
		ptr->PokeDrag.OrgVec.x = 0;
		ptr->PokeDrag.OrgVec.y = 0;
		ptr->PokeDrag.OrgVec.z = 0;
		ptr->PokeDrag.Point.x = 0;
		ptr->PokeDrag.Point.y = 0;
		ptr->PokeDrag.IconTbl = NULL;
		ptr->PokeDrag.IconType = ICON_TYPE_NONE;
	}

	//ゴースト非表示
	CLACT_SetDrawFlag( ptr->Ghost.Clact, 0 );

}

//------------------------------------------------------------------
/**
 * @brief	ポケモンアイコンキャラ・パレット転送
 *
 * @param	ポケモンデータポインタ
 * @param	バッファ
 * @param	ナンバー
 * @param	アイコンアクターポインタ
 * @param	展開一時バッファ
 * @param	VRAMオフセット
 *
 * @return	none
 */
//------------------------------------------------------------------
static void TransPokeIconCharaPal(BOX_POKE_DATA *inData, POKEBUF *pokeBuf, int no,
		CLACT_WORK_PTR icon, void *buf, ARCHANDLE* handle, const u32 inOfs)
{
	u32 dataidx;
	NNSG2dCharacterData *chara;
	POKEBUF *pbuf = pokeBuf + no;

	if(icon){
		// ポケモンのデータインデックス番号を取得
		dataidx = PokeIconCgxArcIndexGetByMonsNumber( inData->MonsNo, inData->Egg, inData->Form );
		// ポケモンキャラクタをバッファに転送
		GetCharData(dataidx, &chara, buf, handle);

		MI_CpuCopyFast(chara->pRawData, pbuf->CharBuf, POKEICON_TRANS_SIZE);
		pbuf->Adrs = (inOfs + no*POKEICON_TRANS_CHARA)*0x20;
		pbuf->Icon = icon;
		pbuf->PalNo = PokeIconPalNumGet( inData->MonsNo, inData->Form, inData->Egg )+POKEICON_PAL_OFFSET;
		// パレット設定(リクエスト反映はアクターのVブランク描画関数で行われる)
		// Vブランク期間中処理でコールしていたが、
		// それでは書き換えの瞬間パレットが旧パレットのものとなってしまうので、ここでコールするように変更
		CLACT_PaletteNoChg(icon, pbuf->PalNo);
	}else {
		pbuf->Icon = NULL;
	}
}

//------------------------------------------------------------------
/**
 * @brief	キャラ取得
 *
 * @param	インデックス
 * @param	キャラデータ構造体ポインタ
 * @param	格納バッファ
 * @param	アーカイブハンドル
 *
 * @return	none
 */
//------------------------------------------------------------------
static void GetCharData(u32 dataIdx, NNSG2dCharacterData** charData, void *arcData, ARCHANDLE* handle)
{
  ArchiveDataLoadByHandle(handle, dataIdx, arcData);
  NNS_G2dGetUnpackedBGCharacterData( arcData, charData );
}

//------------------------------------------------------------------
/**
 * @brief	ボックスタイトルの表示
 * @param	ptr		ワークポインタ
 * @param	inBoxNumber	ボックスナンバー
 * @return	NONE
 */
//------------------------------------------------------------------
static void DrawBoxTitle(POKE_SELECT_WORK_PTR ptr, int inBoxNumber)
{
	STRBUF * msg;
	//手持ちかどうかで分岐
	if (inBoxNumber == MYPARTY_BOX){
		MSGDATA_MANAGER *msgman;
		//アーカイブから展開して表示
		msgman = MSGMAN_Create(MSGMAN_TYPE_DIRECT, ARC_MSG, NARC_msg_poke_select_dat, ptr->HeapID);
		msg = MSGMAN_AllocString(msgman, POKE_SEL_TEMOCHI);
		MSGMAN_Delete(msgman);
	}else{
		msg = STRBUF_Create(BOX_TITLE_STR_BUFF, ptr->HeapID);
		//ボックス名取得
		ptr->GetDataFuncTbl.GetBoxName(msg, ptr->AccessWork.BoxData, inBoxNumber);
	}

	GF_BGL_BmpWinDataFill(&(ptr->TitleWin), TITLE_FONT_COLOR);

	GF_STR_PrintColor(&(ptr->TitleWin), FONT_SYSTEM, msg, TITLE_WRITE_OFS, 0, MSG_NO_PUT, TITLE_FONT_COLOR, NULL);
	GF_BGL_BmpWinOn(&(ptr->TitleWin));

	STRBUF_Delete(msg);
}

//------------------------------------------------------------------
/**
 * @brief	「やめる」の表示
 * @param	ptr		ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void DrawExit(POKE_SELECT_WORK_PTR ptr)
{
	STRBUF * msg;
	MSGDATA_MANAGER *msgman;
	//アーカイブから展開して表示
	msgman = MSGMAN_Create(MSGMAN_TYPE_DIRECT, ARC_MSG, NARC_msg_poke_select_dat, ptr->HeapID);
	msg = MSGMAN_AllocString(msgman, POKE_SEL_EXIT);

	GF_BGL_BmpWinDataFill(&(ptr->ExitWin), MSG_TFONT_COLOR);

	if (ptr->CancelOK){
		GF_STR_PrintColor(&(ptr->ExitWin), FONT_TOUCH, msg, 0, 0, MSG_NO_PUT, MSG_TFONT_COLOR, NULL);
	}
	GF_BGL_BmpWinOn(&(ptr->ExitWin));

	STRBUF_Delete(msg);
	MSGMAN_Delete(msgman);
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	BGセットアップ
 * @param	ini			BGL
 * @param	inHeapID	ヒープID
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetUpBG(GF_BGL_INI * ini, const int inHeapID)
{
	BgInit(ini);

	// 上下画面をひっくり返す

	sys.disp3DSW = DISP_3D_TO_SUB;

	GF_Disp_DispSelect();

	// メイン画面ＢＧパレット転送
	ArcUtil_PalSet(ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_box_bg_nclr, PALTYPE_MAIN_BG, 0, 32*6, inHeapID);
	// メイン画面BG1キャラ転送
	ArcUtil_BgCharSet(ARC_POKESEL_GRA, NARC_poke_sel_poke_sel_box_lz_cngr, ini,
			    GF_BGL_FRAME2_M, 0, 10*16*0x20, 1, inHeapID);

	//1キャラ目をＮＵＬＬデータでフィルする
	GF_BGL_CharFill(ini, GF_BGL_FRAME0_M, 0, 1 ,0);
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	BG初期化
 * @param	ini		BGL
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void BgInit(GF_BGL_INI * ini)
{
  {	/* MAIN DISP BG0 */
    GF_BGL_BGCNT_HEADER MBg0_Data = {
      0, 0, 0x800, 0,
      GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
      GX_BG_SCRBASE_0xe000, GX_BG_CHARBASE_0x00000,
      GX_BG_EXTPLTT_01, 0, 0, 0, FALSE
    };
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME0_M, &MBg0_Data, GF_BGL_MODE_TEXT );
    GF_BGL_ScrClear( ini, GF_BGL_FRAME0_M );
  }

  {	/* MAIN DISP BG1 */
    GF_BGL_BGCNT_HEADER MBg1_Data = {
      0, 0, 0x800, 0,
      GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
      GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x08000,
      GX_BG_EXTPLTT_01, 1, 0, 0, FALSE
    };
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME1_M, &MBg1_Data, GF_BGL_MODE_TEXT );
    GF_BGL_ScrClear( ini, GF_BGL_FRAME1_M );
  }

  {	/* MAIN DISP BG2 */
    GF_BGL_BGCNT_HEADER MBg2_Data = {
      0, 0, 0x800, 0,
      GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
      GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x08000,
      GX_BG_EXTPLTT_23, 3, 0, 0, FALSE
    };
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME2_M, &MBg2_Data, GF_BGL_MODE_TEXT );
    GF_BGL_ScrClear( ini, GF_BGL_FRAME2_M );
  }

  {	/* MAIN DISP BG3 */
    GF_BGL_BGCNT_HEADER MBg3_Data = {
      0, 0, 0x800, 0,
      GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
      GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x08000,
      GX_BG_EXTPLTT_23, 2, 0, 0, FALSE
    };
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME3_M, &MBg3_Data, GF_BGL_MODE_TEXT );
    GF_BGL_ScrClear( ini, GF_BGL_FRAME3_M );
  }
}

//------------------------------------------------------------------
/**
 * @brief	同じボックスならばアイコン表示+半透明化
 * @param	ptr			ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void CheckSelectPokemonIcon(POKE_SELECT_WORK_PTR ptr)
{
	int i;
	for(i = 0; i < ptr->SelectPokeMax; i++){
		if(ptr->Mark[i].PokeNo != POKEMON_NOSELECT && ptr->Mark[i].BoxNo == ptr->CurrentBox){
			CLACT_SetDrawFlag(ptr->Mark[i].Icon, 1);
			//半透明化
			CLACT_ObjModeSet( ptr->Icon[ptr->Mark[i].PokeNo].Clact, GX_OAM_MODE_XLU );
		} else {
			CLACT_SetDrawFlag(ptr->Mark[i].Icon, 0);
		}
	}
}

//手持ちアクセス
//------------------------------------------------------------------
/**
 * @brief	手持ちポケモンからindex番目のポケモンを返す
 *
 * @param	ptr			ワークポインタ
 * @param	inIndex		インデックス
 * @param 	outDara		ポケモンデータ格納バッファ
 *
 * @return	BOOL	TRUE:ポケモンいる		FALSE:ポケモンいない
 */
//------------------------------------------------------------------
static void GetMyPartyPokeData(POKE_SELECT_WORK_PTR ptr, const int inIndex, BOX_POKE_DATA *outData )
{
	POKEMON_PARAM* param = PokeParty_GetMemberPointer(ptr->AccessWork.MyParty, inIndex);

	//モンスターナンバー
	outData->MonsNo = PokeParaGet(param, ID_PARA_monsno, NULL);
	//卵フラグ
	outData->Egg = PokeParaGet(param, ID_PARA_tamago_flag, NULL);
	//フォーム
	outData->Form = PokeParaGet(param, ID_PARA_form_no, NULL);
	//アイテム
	outData->Item = PokeParaGet(param, ID_PARA_item, NULL);
	//カスタムボール
	outData->Ball = 0;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモンアイコンの返却
 *
 * @param	ptr				ワークポインタ
 * @param	inTargetIdx		対象インデックス
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void ReturnPokeIcon(POKE_SELECT_WORK_PTR ptr, const int inTargetIdx)
{
	//決定マーキングを解除
	int clear_trgt = ptr->DropIconData[inTargetIdx].MarkIndex;
	int box_no = ptr->Mark[clear_trgt].BoxNo;
	int poke_no = ptr->Mark[clear_trgt].PokeNo;

	CLACT_SetDrawFlag(ptr->Mark[clear_trgt].Icon, 0);
	ptr->Mark[clear_trgt].PokeNo = POKEMON_NOSELECT;
	ptr->Selected--;
	//現在ボックス番号と、解除したマーキングのボックス番号が一緒ならば半透明ＯＢＪを解除
	if (box_no == ptr->CurrentBox){
		CLACT_ObjModeSet( ptr->Icon[poke_no].Clact, GX_OAM_MODE_NORMAL );
	}else{	//ボックスが違う場合は煙りエフェクト発生
		//ポケの位置取得して、煙の位置にセット
		CLACT_SetMatrix(ptr->Smog, CLACT_GetMatrix(ptr->DropIcon[inTargetIdx].Clact));
		//煙り表示
		CLACT_SetDrawFlag(ptr->Smog,1);
		//アニメ開始
		CLACT_AnmChg(ptr->Smog, SMOG_ANM_OFS);
	}
	ptr->DropIconData[inTargetIdx].Valid = FALSE;

	//ドロップ枠を空ける
	CLACT_SetDrawFlag( ptr->DropIcon[inTargetIdx].Clact, 0 );
	ptr->DropPoint[inTargetIdx].Drop = FALSE;
}

//情報メッセージ関連
//--------------------------------------------------------------------------------------------
/**
 * ウィンドウセットアップ
 *
 * @param	ptr			ワークポインタ
 * @param	inMsgID		メッセージID
 * @param	inFont		フォント
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetupMsgWindow(POKE_SELECT_WORK_PTR ptr, const int inMsgID, const int inFont)
{
	STRBUF * msg;
	MSGDATA_MANAGER *msgman;

	TalkWinGraphicSet(ptr->bgl, GF_BGL_FRAME0_M, POKEMON_TFRAMECHR, POKEMON_TFRAMECOL, 0, ptr->HeapID);

	//ウィンドウ作成
	GF_BGL_BmpWinAdd(ptr->bgl, &ptr->MsgWin, GF_BGL_FRAME3_M,
		     MSG_WIN_X, MSG_WIN_Y, MSG_WIN_W, MSG_WIN_H,
		     FONT_PALNO_NORMAL, MSG_BASE);

	//アーカイブから展開して表示
    msgman = MSGMAN_Create(MSGMAN_TYPE_DIRECT, ARC_MSG, NARC_msg_poke_select_dat, ptr->HeapID);
	msg = MSGMAN_AllocString(msgman, inMsgID);

	GF_BGL_BmpWinDataFill(&(ptr->MsgWin), MSG_FONT_COLOR);

	GF_STR_PrintColor(&ptr->MsgWin, inFont, msg, 0, 0, MSG_NO_PUT, MSG_FONT_COLOR, NULL);
    STRBUF_Delete(msg);//<一括表示なので、メモリをここで消してもOK
    MSGMAN_Delete(msgman);

    GF_BGL_BmpWinOn(&ptr->MsgWin);
	//ウィンドウ表示
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG3, VISIBLE_ON );

}

//--------------------------------------------------------------------------------------------
/**
 * ポケモン選べメッセージ表示
 *
 * @param	ptr		ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void DispSelectMsg(POKE_SELECT_WORK_PTR ptr)
{
	if (ptr->SelectPokeMax == 1){
		//メッセージ表示
		SetupMsgWindow(ptr, POKE_SEL_PHC, FONT_TALK);
	}
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモン選べメッセージ削除
 *
 * @param	ptr		ワークポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void DelSelectMsgWin(POKE_SELECT_WORK_PTR ptr)
{
	if (ptr->SelectPokeMax == 1){
		if ( GF_BGL_BmpWinGet_BglIni( &ptr->MsgWin ) != NULL ){
			//メッセージウィンドウ削除
			GF_BGL_BmpWinDel(&ptr->MsgWin);
		}
	}
}

//------------------------------------------------------------------
/**
 * @brief	ウィンドウを消す
 * @param	win		BMPウィンドウ
 * @param	inFrmVanish		枠を消すか？
 * @return	NONE
 */
//------------------------------------------------------------------
static void DeleteWindow(GF_BGL_BMPWIN *win, const BOOL inFrmVanish)
{
  if(win->ini){
///    BmpTalkWinClear(win, WINDOW_TRANS_ON);

	if (inFrmVanish){
		GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG3, VISIBLE_OFF );
	}
    GF_BGL_BmpWinOff(win);
    GF_BGL_BmpWinDel(win);
  }
}

//------------------------------------------------------------------
/**
 * @brief	選択結果をコピー
 * @param	ptr			ポケモン選択ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void CopyResult(POKE_SELECT_WORK_PTR ptr)
{
	int i;
	for (i=0;i<ptr->SelectPokeMax;i++){
		ptr->Result[i].BoxIdx = ptr->DropIconData[i].BoxIndex;
		ptr->Result[i].BoxPos = ptr->DropIconData[i].PokeIndex;
	}
}

//------------------------------------------------------------------
/**
 * @brief	セルアクター削除
 * @param	ptr			ポケモン選択ワークポインタ
 * @return	NONE
 */
//------------------------------------------------------------------
static void DeleteCellActor(POKE_SELECT_WORK_PTR ptr)
{
	int i;
	//ポケモンアイコン
	for(i = 0; i < POKEMON_ICON_MAX; i++){
		if(ptr->Icon[i].Clact){		//ポケモン
			CLACT_Delete(ptr->Icon[i].Clact);
		}
	}

	//ドロップアイコン
	for(i = 0; i < ptr->SelectPokeMax; i++){
		if(ptr->DropIcon[i].Clact){		//ポケモン
			CLACT_Delete(ptr->DropIcon[i].Clact);
		}
	}

	//選択マーク
	for(i = 0; i < ptr->SelectPokeMax; i++){
		if(ptr->Mark[i].Icon){
			CLACT_Delete(ptr->Mark[i].Icon);
		}
	}
	// やじるしとか「やめる」とか
	if(ptr->Cancel)	CLACT_Delete(ptr->Cancel);
	if(ptr->ArrowL)	CLACT_Delete(ptr->ArrowL);
	if(ptr->ArrowR)	CLACT_Delete(ptr->ArrowR);
	if(ptr->Smog)	CLACT_Delete(ptr->Smog);

	//カーソル
	if(ptr->Curssor) CLACT_Delete(ptr->Curssor);

	//ドロップ禁止パネル
	{
		u8 max = SELECT_POKE_APP_MAX-ptr->SelectPokeMax;
		for(i=0;i<max;i++){
			if(ptr->Panel[i]) CLACT_Delete(ptr->Panel[i]);
		}
	}
}

//------------------------------------------------------------------
/**
 * @brief	キーでカーソル移動
 *
 * @param	ptr				ポケモン選択ワークポインタ
 * @return	none
 */
//------------------------------------------------------------------
static void MoveCursor(POKE_SELECT_WORK_PTR ptr)
{
	LINK_AREA_ID link_area_id;
	u8 idx;
	VecFx32 vec;
	BOOL set = FALSE;

	//何処にいるかを調べる
	link_area_id  = KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr);
	//インデックス取得
	idx = KeyLink_GetIndex(ptr->KeyLinkContPtr);

	vec.z = 0;
	switch(link_area_id){
	case LINK_AREA_BOX_NAME:
		vec.x = FX32_ONE*BOX_NAME_POS_X;
		vec.y = FX32_ONE*BOX_NAME_POS_Y;
		set = TRUE;
		break;
	case LINK_AREA_BOX:
	case LINK_AREA_MY_PARTY:
		{
			u8 x,y;
			x = idx % 6;
			y = idx / 6;
			vec.x = FX32_ONE * (x * POKEMON_WIDTH  + POKEMON_BASEX);
			vec.y = FX32_ONE * (y * POKEMON_HEIGHT + POKEMON_BASEY);
		}
		set = TRUE;
		break;
	case LINK_AREA_DROP:
		{
			u8 h;
			h = idx;		//0 〜 2
			vec.x = FX32_ONE * (DROP_ICON_X_BASE);
			vec.y = FX32_ONE * (DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS + DROP_ICON_DRAW_OFS);
		}
		set = TRUE;
		break;
	case LINK_AREA_DROP_CLOSE:
		{
			u8 h;
			h = idx;		//0 〜 2
			vec.x = FX32_ONE * (DROP_ICON_X_BASE);
			vec.y = FX32_ONE * (DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS + DROP_ICON_DRAW_OFS);

			//キードラッグ中ならばポケモンアイコン移動
			if (ptr->KeyDrag){
				VecFx32 poke_vec;
				poke_vec = vec;
				poke_vec.y -= GRASP_OFS;
				//ドラッグ中。対象ポケモンを移動
				CLACT_SetMatrix(ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact, &poke_vec);

				//ドロップ座標に決定
				ptr->PokeDrag.Point.x = (DROP_ICON_X_BASE);
				ptr->PokeDrag.Point.y = (DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS + DROP_ICON_DRAW_OFS);
			}
		}
		set = TRUE;
		break;
	case LINK_AREA_EXIT:
		vec.x = FX32_ONE*BTN_POS_X_TERMINATE;
		vec.y = FX32_ONE*BTN_POS_Y_TERMINATE;
		set = TRUE;
		break;
	}

	if (set){
		//カーソル移動
		CLACT_SetMatrix(ptr->Curssor, &vec);
		//コールバック
		CallBack(ptr);
	}
}

//------------------------------------------------------------------
/**
 * @brief	Aボタン押下
 * @param	ptr				ポケモン選択ワークポインタ
 * @return	rc				リターンコード
 */
//------------------------------------------------------------------
static SELECT_MAIN_RC ButtonPushFunc( POKE_SELECT_WORK_PTR ptr )
{
	LINK_AREA_ID link_area_id;
	u8 idx;
	VecFx32 vec;
	int seltype;
	SELECT_MAIN_RC rc = SELECT_MAIN_RC_NONE;

	//何処にいるかを調べる
	link_area_id  = KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr);
	//インデックス取得
	idx = KeyLink_GetIndex(ptr->KeyLinkContPtr);

	switch(link_area_id){
	case LINK_AREA_BOX:
	case LINK_AREA_MY_PARTY:
		seltype = SelectPokemon(ptr, idx);
		if (seltype == SELECT_POKEMON_SELECT){
			//ドラッグ開始
			SetDragPokemon(ptr, BOX_POKE_ICON, idx);
			//自動でドロップエリアに移動（アニメ起動）
			{
				//ドロップエリアの空き場所を検索
				int i;
				for (i=0;i<ptr->SelectPokeMax;i++){
					VecFx32 vec = {0,0,0};
					//すでにドロップ済みかを調べる
					if(!ptr->DropPoint[i].Drop){
						//ドロップ座標に決定
						u8 h;
						h = i;		//0 〜 2
						ptr->PokeDrag.Point.x = (DROP_ICON_X_BASE);
						ptr->PokeDrag.Point.y = (DROP_ICON_Y_BASE + h * DROP_ICON_Y_OFS + DROP_ICON_DRAW_OFS);

						vec.x = FX32_ONE * ptr->PokeDrag.Point.x;
						vec.y = FX32_ONE * ptr->PokeDrag.Point.y;

						//指定ポケモンアイコンとカーソルを空き位置へ
						//対象ポケモン
						{
							VecFx32 poke_vec;
							poke_vec = vec;
							poke_vec.y -= GRASP_OFS;
							CLACT_SetMatrix(ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact, &poke_vec);
						}
						//カーソル移動
						CLACT_SetMatrix(ptr->Curssor, &vec);

						//キーコントロールエリアを変更（ドロップクローズへ）
						KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_DROP_CLOSE , i);
						break;
					}//end if
				}//end for
			}

			//キードラッグ有効
			ptr->KeyDrag = TRUE;

			rc = SELECT_MAIN_RC_SELECT;
		}
		break;
	case LINK_AREA_DROP:
		seltype = SelectDropPokemon(ptr, idx);
		if (seltype == SELECT_POKEMON_SELECT){
			//ドラッグ開始	持ち上げるだけ
			SetDragPokemon(ptr, DROP_POKE_ICON, idx);
			//対象ポケモン
			{
				VecFx32 poke_vec;
				poke_vec = *CLACT_GetMatrix(ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact);
				poke_vec.y -= GRASP_OFS;
				CLACT_SetMatrix(ptr->PokeDrag.IconTbl[ptr->PokeDrag.TargetIdx].Clact, &poke_vec);
			}

			//キードラッグ有効
			ptr->KeyDrag = TRUE;

			//エントリー解除確認シーケンスへ
			ptr->Seq = MAIN_SEQ_ENTRY_POKE_CANCEL;
			rc = SELECT_MAIN_RC_SELECT;
		}
		break;
	case LINK_AREA_EXIT:
		PushExit(ptr);
		rc = SELECT_MAIN_RC_CANCEL;
		break;

	case LINK_AREA_DROP_CLOSE:
		DropPokemon(ptr);
		break;
	}

	return rc;
}

//------------------------------------------------------------------
/**
 * @brief	Bボタン押下
 * @param	ptr				ポケモン選択ワークポインタ
 * @return	rc				リターンコード
 */
//------------------------------------------------------------------
static SELECT_MAIN_RC ButtonCancelFunc( POKE_SELECT_WORK_PTR ptr )
{
	LINK_AREA_ID link_area_id;
	SELECT_MAIN_RC rc = SELECT_MAIN_RC_NONE;

	//何処にいるかを調べる
	link_area_id  = KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr);

	switch(link_area_id){
	case LINK_AREA_DROP_CLOSE:
		//SE
		Snd_SePlay(SEQ_SE_DP_SELECT);
		//つかんでるポケモンを戻す（ドロップ失敗とみなす）
		DropResultFunc(ptr ,DROP_NG);
		break;
	case LINK_AREA_EXIT:
		PushExit(ptr);
		rc = SELECT_MAIN_RC_CANCEL;
		break;
	default:
		//やめるがある場合はやめるへジャンプ
		if (ptr->CancelOK){	//やめるへジャンプ
			VecFx32 vec;
			KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_EXIT, 0);
			vec.x = FX32_ONE*BTN_POS_X_TERMINATE;
			vec.y = FX32_ONE*BTN_POS_Y_TERMINATE;
			vec.z = 0;
			CLACT_SetMatrix(ptr->Curssor, &vec);
			//SE
			Snd_SePlay(SEQ_SE_DP_SELECT);
		}
	}

	return rc;
}

//------------------------------------------------------------------
/**
 * @brief	左ボタンの反応処理
 * @param	ptr				ポケモン選択ワークポインタ
 * @return	none
 */
//------------------------------------------------------------------
static void PushArrowL(POKE_SELECT_WORK_PTR ptr)
{
	if(ptr->CurrentBox == 0){
		ptr->CurrentBox = ptr->BoxNumMax - 1;
	}else{
		ptr->CurrentBox--;
	}
	//アニメ
	CLACT_AnmChg(ptr->ArrowL, L_ARROW_ICON_ANM_OFS+1);
	RedrawBox(ptr);
	Snd_SePlay(SEQ_SE_DP_SELECT);

	//ボックスが手持ちになったか？
	if ( ptr->CurrentBox == MYPARTY_BOX ){
		//今までいたエリアがボックスエリアか？
		if( KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr)==LINK_AREA_BOX ){
			//現在のカーソル位置を手持ちボックスの位置へ変換
			u8 idx = KeyLink_GetIndex(ptr->KeyLinkContPtr);
			u8 new_idx = idx % MYPARTY_BOX_SEL_MAX;	//0〜5
			//エリアを手持ちに変更
			KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_MY_PARTY, new_idx);
			//カーソルを範囲内へ移動
			{
				VecFx32 vec;
				//カーソル位置変更
				vec.x = FX32_ONE * (POKEMON_BASEX + (POKEMON_WIDTH*new_idx));
				vec.y = FX32_ONE * (POKEMON_BASEY);
				vec.z = 0;
				CLACT_SetMatrix(ptr->Curssor, &vec);
			}
		}
	}else if ( KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr)==LINK_AREA_MY_PARTY){	//今までいたエリアが手持ちエリアか？
		u8 idx = KeyLink_GetIndex(ptr->KeyLinkContPtr);
		//エリアをボックスに変更
		KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_BOX, idx);
	}
}

//------------------------------------------------------------------
/**
 * @brief	右ボタンの反応処理
 * @param	ptr				ポケモン選択ワークポインタ
 * @return	none
 */
//------------------------------------------------------------------
static void PushArrowR(POKE_SELECT_WORK_PTR ptr)
{
	if(++ptr->CurrentBox == ptr->BoxNumMax){
		ptr->CurrentBox = 0;
	}
	//アニメ
	CLACT_AnmChg(ptr->ArrowR, R_ARROW_ICON_ANM_OFS+1);
	RedrawBox(ptr);
	Snd_SePlay(SEQ_SE_DP_SELECT);

	//ボックスが手持ちになったか？
	if ( ptr->CurrentBox == MYPARTY_BOX ){
		//今までいたエリアがボックスエリアか？
		if( KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr)==LINK_AREA_BOX ){
			//現在のカーソル位置を手持ちボックスの位置へ変換
			u8 idx = KeyLink_GetIndex(ptr->KeyLinkContPtr);
			u8 new_idx = idx % MYPARTY_BOX_SEL_MAX;	//0〜5
			//エリアを手持ちに変更
			KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_MY_PARTY, new_idx);
			//カーソルを範囲内へ移動
			{
				VecFx32 vec;
				//カーソル位置変更
				vec.x = FX32_ONE * (POKEMON_BASEX + (POKEMON_WIDTH*new_idx));
				vec.y = FX32_ONE * (POKEMON_BASEY);
				vec.z = 0;
				CLACT_SetMatrix(ptr->Curssor, &vec);
			}
		}
	}else if ( KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr)==LINK_AREA_MY_PARTY){	//今までいたエリアが手持ちエリアか？
		u8 idx = KeyLink_GetIndex(ptr->KeyLinkContPtr);
		//エリアをボックスに変更
		KeyLink_SetPosition(ptr->KeyLinkContPtr, LINK_AREA_BOX, idx);
	}
}

//------------------------------------------------------------------
/**
 * @brief	やめるボタンの反応処理
 * @param	ptr				ポケモン選択ワークポインタ
 * @return	none
 */
//------------------------------------------------------------------
static void PushExit(POKE_SELECT_WORK_PTR ptr)
{
	CLACT_AnmChg(ptr->Cancel, CANCEL_ICON__ANM_OFS+1);
	Snd_SePlay(SEQ_SE_DP_SELECT);
}

//------------------------------------------------------------------
/**
 * @brief	コールバック
 * @param	ptr				ポケモン選択ワークポインタ
 * @return	none
 */
//------------------------------------------------------------------
static void CallBack(POKE_SELECT_WORK_PTR ptr)
{
	if (ptr->CallBackFunc != NULL){
		int pos,no;
		int seltype;
		LINK_AREA_ID link_area_id;
		u8 idx;
		//現在のカーソル位置を調べて、そこにポケがいる場合は
		//そのポケのボックス位置を調べる ポケがいない場合は-1
		pos = -1;
		no = -1;
		//カレントエリアを調べる
		link_area_id  = KeyLink_GetLinkAreaID(ptr->KeyLinkContPtr);
		//ボックス・手持ち・ドロップ以外はポケなし
		switch(link_area_id){
		case LINK_AREA_BOX:
		case LINK_AREA_MY_PARTY:
			no = ptr->CurrentBox;
			//インデックス取得
			idx = KeyLink_GetIndex(ptr->KeyLinkContPtr);
			seltype = CheckSelPoke(ptr, idx);
			if (seltype == SELECT_POKEMON_SELECT){
				pos = idx;
			}
			break;
		case LINK_AREA_DROP:
			//インデックス取得
			idx = KeyLink_GetIndex(ptr->KeyLinkContPtr);
			seltype = CheckSelDropPoke(ptr, idx);
			if (seltype == SELECT_POKEMON_SELECT){
				//ボックス位置を調べる
				no = ptr->DropIconData[idx].BoxIndex;
				pos = ptr->DropIconData[idx].PokeIndex;
			}
			break;
		case  LINK_AREA_DROP_CLOSE:
			//つかんでるポケを上画面に表示
			if (ptr->PokeDrag.State){
				no = ptr->CurrentBox;
				pos = ptr->PokeDrag.TargetIdx;
				OS_Printf("%d,%d\n",no, pos);
			}
			break;
		}

		if ( (ptr->TmpBoxNo != no)||(ptr->TmpBoxPos != pos) ){
			ptr->CallBackFunc(no, pos, ptr->CallBackWk);
		}
		ptr->TmpBoxNo = no;
		ptr->TmpBoxPos = pos;
	}
}

//------------------------------------------------------------------
/**
 * @brief	パッシブ状態セット
 * @param	none
 * @return	none
 */
//------------------------------------------------------------------
static void SetPassive(void)
{
	G2_SetBlendBrightness(
		GX_BLEND_PLANEMASK_BG1 | GX_BLEND_PLANEMASK_BG2 | GX_BLEND_PLANEMASK_OBJ,
		BRIGHT_VAL
	);
}

//------------------------------------------------------------------
/**
 * @brief	パッシブ状態解除
 * @param	none
 * @return	none
 */
//------------------------------------------------------------------
static void ClearPassive(void)
{
	G2_BlendNone();
	//半透明設定
	G2_SetBlendAlpha( GX_BLEND_PLANEMASK_NONE,
			GX_BLEND_PLANEMASK_BG2, BLEND_EVA, BLEND_EVB );
}